commit 55a80d227ab9f2c0932b62f709faadc8a5a0f5d3 Author: “wangzihua” Date: Tue Dec 23 23:03:39 2025 +0800 first diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..49f3616 --- /dev/null +++ b/pom.xml @@ -0,0 +1,437 @@ + + 4.0.0 + + net.lab1024 + yun-parent + 3.0.0 + pom + + yun-parent + yun project + + + yun-base + yun-admin + + + + UTF-8 + UTF-8 + 1.8 + 2.7.18 + 2.0.8 + 5.8.16 + 3.5.12 + 9.3.0 + 3.9.1 + 1.7.0 + 4.5.0 + 2.0.57 + 1.2.25 + 1.4.2 + 20.0 + 0.10.2 + 2.19.0 + 3.18.0 + 4.5.0 + 1.27.1 + 1.18.0 + 1.13.1 + 1.2.0 + 5.4.1 + 2.31.78 + 5.8.39 + 2.4.1 + 3.1 + 1.44.0 + 2.7.0 + 1.80 + 1.2.0 + 3.25.0 + 2.4 + 2.3.34 + 1.21.1 + 2.9.4 + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${springboot.version} + pom + import + + + + + com.baomidou + mybatis-plus-bom + ${mybatis-plus.version} + pom + import + + + + + org.springframework + spring-mock + ${spring-mock.version} + + + commons-logging + commons-logging + + + + + + org.springframework.security + spring-security-crypto + ${spring-security-crypto.version} + + + + com.mysql + mysql-connector-j + ${mysql-connector-j.version} + + + + p6spy + p6spy + ${p6spy.version} + + + + org.springdoc + springdoc-openapi-ui + ${springdoc-openapi-ui.version} + + + + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter + ${knife4j.version} + + + + com.alibaba + fastjson + ${fastjson.version} + + + + com.alibaba + druid + ${druid.version} + + + + com.googlecode.concurrentlinkedhashmap + concurrentlinkedhashmap-lru + ${google-linkedhashmap.version} + + + + com.google.guava + guava + ${google-guava.version} + + + + org.reflections + reflections + ${reflections.version} + + + guava + com.google.guava + + + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + org.apache.commons + commons-compress + ${commons-compress.version} + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + software.amazon.awssdk + s3 + ${awssdk-s3.version} + + + commons-logging + commons-logging + + + + + + org.apache.commons + commons-text + ${commons-text.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + + org.apache.velocity + velocity-engine-core + ${velocity-engine-core.version} + + + org.apache.velocity.tools + velocity-tools-generic + ${velocity-tools.version} + + + + + + cn.dev33 + sa-token-spring-boot-starter + ${sa-token.version} + + + + + cn.dev33 + sa-token-redis-jackson + ${sa-token.version} + + + + + + + org.lionsoul + ip2region + ${ip2region.version} + + + + org.bouncycastle + bcprov-jdk18on + ${bcprov.version} + + + + cn.idev.excel + fastexcel + ${fast-excel.version} + + + logback-classic + ch.qos.logback + + + org.bouncycastle + bcprov-jdk15on + + + + + + org.apache.poi + poi + ${poi.version} + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + org.apache.poi + poi-scratchpad + ${poi.version} + + + + org.apache.poi + poi-ooxml-full + ${poi.version} + + + + net.1024lab + smartdb + ${smartdb.version} + + + + + org.redisson + redisson-spring-boot-starter + ${redisson.version} + + + org.springframework.boot + spring-boot-starter-actuator + + + org.redisson + redisson-spring-data-32 + + + objenesis + org.objenesis + + + + + org.redisson + redisson-spring-data-27 + ${redisson.version} + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.jsoup + jsoup + ${jsoup.version} + + + + org.freemarker + freemarker + ${freemarker.version} + + + + org.apache.tika + tika-core + ${tika.version} + + + + + + + + ${project.name}-${profiles.active}-${project.version} + + + false + src/main/resources + + dev/* + test/* + pre/* + prod/* + + + + + src/main/resources/${profiles.active} + true + + *.yaml + + + + + src/main/resources/${profiles.active} + false + + *.* + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + 1.8 + 1.8 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${springboot.version} + + + + + + + + dev + + dev + + + true + + + + + test + + test + + + + + pre + + pre + + + + + prod + + prod + + + + + diff --git a/yun-admin/pom.xml b/yun-admin/pom.xml new file mode 100644 index 0000000..4df37b0 --- /dev/null +++ b/yun-admin/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + + net.lab1024 + yun-parent + 3.0.0 + ../pom.xml + + + yun-admin + 3.0.0 + jar + + yun-admin + yun-admin project + + + + + net.lab1024 + yun-base + 3.0.0 + + + com.alibaba + easyexcel + 3.2.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + net.lab1024.sa.admin.AdminApplication + + + + + repackage + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/AdminApplication.java b/yun-admin/src/main/java/net/lab1024/sa/admin/AdminApplication.java new file mode 100644 index 0000000..0d4863c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/AdminApplication.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin; + +import net.lab1024.sa.base.listener.Ip2RegionListener; +import net.lab1024.sa.base.listener.LogVariableListener; +import org.apache.ibatis.annotations.Mapper; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * SmartAdmin 项目启动类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022-08-29 21:00:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@EnableCaching +@EnableScheduling +@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) +@ComponentScan(AdminApplication.COMPONENT_SCAN) +@MapperScan(value = AdminApplication.COMPONENT_SCAN, annotationClass = Mapper.class) +@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class}) +public class AdminApplication { + + public static final String COMPONENT_SCAN = "net.lab1024.sa"; + + public static void main(String[] args) { + SpringApplication application = new SpringApplication(AdminApplication.class); + // 添加 日志监听器,使 log4j2-spring.xml 可以间接读取到配置文件的属性 + application.addListeners(new LogVariableListener(), new Ip2RegionListener()); + application.run(args); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/common/enums/ReviewEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/common/enums/ReviewEnum.java new file mode 100644 index 0000000..f3caf8d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/common/enums/ReviewEnum.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.common.enums; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +public enum ReviewEnum implements BaseEnum { + NOSUBMIT(0, "未提交"), + + APPROVAL(1, "待审批"), + + REVIEW(2, "审批中"), + + PASS(3, "已通过"), + + REFUSE(4, "拒绝"); + + ReviewEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + private Integer value; + private String desc; + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/config/MvcConfig.java b/yun-admin/src/main/java/net/lab1024/sa/admin/config/MvcConfig.java new file mode 100644 index 0000000..694eb0d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/config/MvcConfig.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.admin.interceptor.AdminInterceptor; +import net.lab1024.sa.base.config.SwaggerConfig; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.Resource; + +/** + * web相关配置 + */ +@Configuration +public class MvcConfig implements WebMvcConfigurer { + + @Resource + private AdminInterceptor adminInterceptor; + + + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(adminInterceptor) + .excludePathPatterns(SwaggerConfig.SWAGGER_WHITELIST) + .addPathPatterns("/**"); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java b/yun-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java new file mode 100644 index 0000000..14d03a3 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect; +import net.lab1024.sa.base.module.support.operatelog.core.OperateLogConfig; +import org.springframework.context.annotation.Configuration; + +/** + * 操作日志切面 配置 + */ +@Configuration +public class OperateLogAspectConfig extends OperateLogAspect{ + + /** + * 配置信息 + */ + @Override + public OperateLogConfig getOperateLogConfig() { + return OperateLogConfig.builder().corePoolSize(1).queueCapacity(10000).build(); + } + + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java b/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java new file mode 100644 index 0000000..c4e42db --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.constant; + +import net.lab1024.sa.base.constant.CacheKeyConst; + +/** + * 缓存 key + */ +public class AdminCacheConst extends CacheKeyConst { + + public static class Department { + + /** + * 部门列表 + */ + public static final String DEPARTMENT_LIST_CACHE = "department_list_cache"; + + /** + * 部门树 + */ + public static final String DEPARTMENT_TREE_CACHE = "department_tree_cache"; + + /** + * 某个部门以及下级的id列表 + */ + public static final String DEPARTMENT_SELF_CHILDREN_CACHE = "department_self_children_cache"; + + /** + * 部门路径 缓存 + */ + public static final String DEPARTMENT_PATH_CACHE = "department_path_cache"; + + } + + /** + * 分类相关缓存 + */ + public static class Category { + + public static final String CATEGORY_ENTITY = "category_cache"; + + public static final String CATEGORY_SUB = "category_sub_cache"; + + public static final String CATEGORY_TREE = "category_tree_cache"; + } + + /** + * 登录相关 + */ + public static class Login { + + /** + * 请求用户信息 + */ + public static final String REQUEST_EMPLOYEE = "login_request_employee"; + + /** + * 请求用户信息权限 + */ + public static final String USER_PERMISSION = "login_user_permission"; + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java b/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java new file mode 100644 index 0000000..7b24127 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java @@ -0,0 +1,11 @@ +package net.lab1024.sa.admin.constant; + +import net.lab1024.sa.base.constant.RedisKeyConst; + +/** + * redis key 常量类 + */ +public class AdminRedisKeyConst extends RedisKeyConst { + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java b/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java new file mode 100644 index 0000000..2726241 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.admin.constant; + +import net.lab1024.sa.base.constant.SwaggerTagConst; + +/** + * swagger + */ +public class AdminSwaggerTagConst extends SwaggerTagConst { + + public static class Business { + public static final String MANAGER_CATEGORY = "ERP进销存-分类管理"; + + public static final String MANAGER_GOODS = "ERP进销存-商品管理"; + + public static final String OA_BANK = "OA办公-银行卡信息"; + + public static final String OA_ENTERPRISE = "OA办公-企业"; + + public static final String OA_INVOICE = "OA办公-发票信息"; + + public static final String OA_NOTICE = "OA办公-通知公告"; + + } + + + public static class System { + + public static final String SYSTEM_LOGIN = "系统-员工登录"; + + public static final String SYSTEM_EMPLOYEE = "系统-员工管理"; + + public static final String SYSTEM_DEPARTMENT = "系统-部门管理"; + + public static final String SYSTEM_MENU = "系统-菜单"; + + public static final String SYSTEM_DATA_SCOPE = "系统-系统-数据范围"; + + public static final String SYSTEM_ROLE = "系统-角色"; + + public static final String SYSTEM_ROLE_DATA_SCOPE = "系统-角色-数据范围"; + + public static final String SYSTEM_ROLE_EMPLOYEE = "系统-角色-员工"; + + public static final String SYSTEM_ROLE_MENU = "系统-角色-菜单"; + + public static final String SYSTEM_POSITION = "系统-职务管理"; + + public static final String SYSTEM_MESSAGE = "系统-消息"; + + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java b/yun-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java new file mode 100644 index 0000000..10ef201 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java @@ -0,0 +1,135 @@ +package net.lab1024.sa.admin.interceptor; + +import cn.dev33.satoken.annotation.SaIgnore; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.strategy.SaAnnotationStrategy; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.base.common.annoation.NoNeedLogin; +import net.lab1024.sa.base.common.code.SystemErrorCode; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.common.util.SmartResponseUtil; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +/** + * admin 拦截器 + */ + +@Component +@Slf4j +public class AdminInterceptor implements HandlerInterceptor { + + @Resource + private LoginService loginService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + // OPTIONS请求直接return + if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { + response.setStatus(HttpStatus.NO_CONTENT.value()); + return false; + } + + boolean isHandler = handler instanceof HandlerMethod; + if (!isHandler) { + return true; + } + + try { + // --------------- 第一步: 根据token 获取用户 --------------- + + String tokenValue = StpUtil.getTokenValue(); + String loginId = (String) StpUtil.getLoginIdByToken(tokenValue); + RequestEmployee requestEmployee = loginService.getLoginEmployee(loginId, request); + + // --------------- 第二步: 校验 登录 --------------- + + Method method = ((HandlerMethod) handler).getMethod(); + NoNeedLogin noNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class); + if (noNeedLogin != null) { + updateActiveTimeout(requestEmployee); + SmartRequestUtil.setRequestUser(requestEmployee); + return true; + } + + if (requestEmployee == null) { + SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID)); + return false; + } + + // 更新活跃 + updateActiveTimeout(requestEmployee); + + + // --------------- 第三步: 校验 权限 --------------- + + SmartRequestUtil.setRequestUser(requestEmployee); + if (SaAnnotationStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class)) { + return true; + } + + // 如果是超级管理员的话,不需要校验权限 + if (requestEmployee.getAdministratorFlag()) { + return true; + } + + SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method); + + } catch (SaTokenException e) { + /* + * sa-token 异常状态码 + * 具体请看: https://sa-token.cc/doc.html#/fun/exception-code + */ + int code = e.getCode(); + if (code == 11041 || code == 11051) { + SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.NO_PERMISSION)); + } else if (code == 11016) { + SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_ACTIVE_TIMEOUT)); + } else if (code >= 11011 && code <= 11015) { + SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID)); + } else { + SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.PARAM_ERROR)); + } + return false; + } catch (Throwable e) { + SmartResponseUtil.write(response, ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR)); + log.error(e.getMessage(), e); + return false; + } + + // 通过验证 + return true; + } + + + /** + * 更新活跃时间 + */ + private void updateActiveTimeout(RequestEmployee requestEmployee) { + if (requestEmployee == null) { + return; + } + StpUtil.updateLastActiveToNow(); + } + + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + // 清除上下文 + SmartRequestUtil.remove(); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java new file mode 100644 index 0000000..c3be511 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.business.category.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 分类类型 枚举 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum CategoryTypeEnum implements BaseEnum { + + /** + * 1 商品 + */ + GOODS(1, "商品"), + + /** + * 2 自定义 + */ + CUSTOM(2, "自定义"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java new file mode 100644 index 0000000..951b55a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java @@ -0,0 +1,63 @@ +package net.lab1024.sa.admin.module.business.category.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO; +import net.lab1024.sa.admin.module.business.category.service.CategoryService; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 类目 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.Business.MANAGER_CATEGORY) +public class CategoryController { + + @Resource + private CategoryService categoryService; + + @Operation(summary = "添加类目 @author 胡克") + @PostMapping("/category/add") + @SaCheckPermission("category:add") + public ResponseDTO add(@RequestBody @Valid CategoryAddForm addForm) { + return categoryService.add(addForm); + } + + @Operation(summary = "更新类目 @author 胡克") + @PostMapping("/category/update") + @SaCheckPermission("category:update") + public ResponseDTO update(@RequestBody @Valid CategoryUpdateForm updateForm) { + return categoryService.update(updateForm); + } + + @Operation(summary = "查询类目详情 @author 胡克") + @GetMapping("/category/{categoryId}") + public ResponseDTO queryDetail(@PathVariable Long categoryId) { + return categoryService.queryDetail(categoryId); + } + + @Operation(summary = "查询类目层级树 @author 胡克") + @PostMapping("/category/tree") + @SaCheckPermission("category:tree") + public ResponseDTO> queryTree(@RequestBody @Valid CategoryTreeQueryForm queryForm) { + return categoryService.queryTree(queryForm); + } + + @Operation(summary = "删除类目 @author 胡克") + @GetMapping("/category/delete/{categoryId}") + @SaCheckPermission("category:delete") + public ResponseDTO delete(@PathVariable Long categoryId) { + return categoryService.delete(categoryId); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java new file mode 100644 index 0000000..c107b26 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.module.business.category.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 类目 dao + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface CategoryDao extends BaseMapper { + + /** + * 根据父级id 类型 查询子类 + * + * @param parentIdList 父级id集合 + * @param deletedFlag 删除标识 + * @return 列表 + */ + List queryByParentId(@Param("parentIdList") List parentIdList, + @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据父级id 类型 查询子类 + * + * @param parentIdList 父级id集合 + * @param categoryType {@link CategoryTypeEnum} + * @param deletedFlag 删除标识 + * @return 列表 + */ + List queryByParentIdAndType(@Param("parentIdList") List parentIdList, + @Param("categoryType") Integer categoryType, + @Param("deletedFlag") Boolean deletedFlag); + + /** + * 某个类型的所有 + */ + List queryByType(@Param("categoryType") Integer categoryType, + @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据类型和id查询 + */ + CategoryEntity selectByTypeAndId(@Param("categoryType") Integer categoryType, @Param("categoryId") Long categoryId); + + /** + * 查看类目 具体条件 看sql + */ + CategoryEntity selectOne(CategoryEntity entity); + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java new file mode 100644 index 0000000..f62dba2 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.business.category.domain.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 类目 基础属性 DTO 类 + * + * @author 胡克 + * @date 2021/1/20 16:17 + */ +@Data +public class CategoryBaseDTO { + + @Schema(description = "类目名称", required = true) + @NotBlank(message = "类目名称不能为空") + @Length(max = 20, message = "类目名称最多20字符") + private String categoryName; + + @SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class) + @CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误") + private Integer categoryType; + + @Schema(description = "父级类目id|可选") + private Long parentId; + + @Schema(description = "排序|可选") + private Integer sort; + + @Schema(description = "备注|可选") + @Length(max = 200, message = "备注最多200字符") + private String remark; + + @Schema(description = "禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java new file mode 100644 index 0000000..97d0310 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.business.category.domain.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 类目 基础属性 DTO 类 + * + * @author 胡克 + * @date 2021/1/20 16:17 + */ +@Data +public class CategorySimpleDTO { + + @Schema(description = "类目id") + private Long categoryId; + + @Schema(description = "类目名称") + private String categoryName; + + @Schema(description = "类目层级全称") + private String categoryFullName; + + @Schema(description = "父级id") + private Long parentId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java new file mode 100644 index 0000000..b8d0a77 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.admin.module.business.category.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 类目 实体类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_category") +public class CategoryEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + private Long categoryId; + + /** + * 类目名称 + */ + private String categoryName; + + /** + * 类目 类型 + * + * @see CategoryTypeEnum + */ + private Integer categoryType; + + /** + * 父级类目id + */ + private Long parentId; + + /** + * 是否禁用 + */ + private Boolean disabledFlag; + + /** + * 排序 + */ + private Integer sort; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java new file mode 100644 index 0000000..c48b3f7 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.business.category.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 类目 添加 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CategoryAddForm { + + @Schema(description = "类目名称", required = true) + @NotBlank(message = "类目名称不能为空") + @Length(max = 100, message = "类目名称最多100字符") + private String categoryName; + + @SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class) + @CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误") + private Integer categoryType; + + @Schema(description = "父级类目id|可选") + private Long parentId; + + @Schema(description = "排序|可选") + private Integer sort; + + @Schema(description = "备注|可选") + @Length(max = 200, message = "备注最多200字符") + private String remark; + + @Schema(description = "禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java new file mode 100644 index 0000000..87bf072 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin.module.business.category.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +/** + * 类目 层级树查询 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CategoryTreeQueryForm { + + @SchemaEnum(desc = "分类类型|可选", value = CategoryTypeEnum.class) + private Integer categoryType; + + @Schema(description = "父级类目id|可选") + private Long parentId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java new file mode 100644 index 0000000..8f12dd2 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.category.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO; + +import javax.validation.constraints.NotNull; + +/** + * 类目 更新 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CategoryUpdateForm extends CategoryAddForm { + + @Schema(description = "类目id") + @NotNull(message = "类目id不能为空") + private Long categoryId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java new file mode 100644 index 0000000..f847b40 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.business.category.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 类目 层级树 vo + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CategoryTreeVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "类目id") + private Long categoryId; + + @Schema(description = "类目名称") + private String categoryName; + + @Schema(description = "类目层级全称") + private String categoryFullName; + + @Schema(description = "父级id") + private Long parentId; + + @Schema(description = "类目id") + private Long value; + + @Schema(description = "类目名称") + private String label; + + @Schema(description = "子类") + private List children; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java new file mode 100644 index 0000000..1436958 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.business.category.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.time.LocalDateTime; + +/** + * 类目 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CategoryVO { + + @Schema(description = "类目名称", required = true) + private String categoryName; + + @SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class) + private Integer categoryType; + + @Schema(description = "父级类目id|可选") + private Long parentId; + + @Schema(description = "排序|可选") + private Integer sort; + + @Schema(description = "备注|可选") + private String remark; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "类目id") + private Long categoryId; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java new file mode 100644 index 0000000..b320bad --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java @@ -0,0 +1,113 @@ +package net.lab1024.sa.admin.module.business.category.manager; + +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminCacheConst; +import net.lab1024.sa.admin.module.business.category.dao.CategoryDao; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 类目 查询 缓存 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class CategoryCacheManager { + + + @Resource + private CategoryDao categoryDao; + + + /** + * 根据类目id 移除缓存 + */ + @CacheEvict(value = {AdminCacheConst.Category.CATEGORY_ENTITY, AdminCacheConst.Category.CATEGORY_SUB, AdminCacheConst.Category.CATEGORY_TREE}, allEntries = true) + public void removeCache() { + log.info("clear CATEGORY ,CATEGORY_SUB ,CATEGORY_TREE"); + } + + /** + * 查詢类目 + * + */ + @Cacheable(AdminCacheConst.Category.CATEGORY_ENTITY) + public CategoryEntity queryCategory(Long categoryId) { + return categoryDao.selectById(categoryId); + } + + /** + * 查询类目 子级 + * + */ + @Cacheable(AdminCacheConst.Category.CATEGORY_SUB) + public List querySubCategory(Long categoryId) { + return categoryDao.queryByParentId(Lists.newArrayList(categoryId), false); + } + + + /** + * 查询类目 层级树 + * 优先查询缓存 + */ + @Cacheable(AdminCacheConst.Category.CATEGORY_TREE) + public List queryCategoryTree(Long parentId, Integer categoryType) { + List allCategoryEntityList = categoryDao.queryByType(categoryType, false); + + List categoryEntityList = allCategoryEntityList.stream().filter(e -> e.getParentId().equals(parentId)).collect(Collectors.toList()); + List treeList = SmartBeanUtil.copyList(categoryEntityList, CategoryTreeVO.class); + treeList.forEach(e -> { + e.setLabel(e.getCategoryName()); + e.setValue(e.getCategoryId()); + e.setCategoryFullName(e.getCategoryName()); + }); + // 递归设置子类 + this.queryAndSetSubCategory(treeList, allCategoryEntityList); + return treeList; + } + + /** + * 递归查询设置类目子类 + * 从缓存查询子类 + * + */ + private void queryAndSetSubCategory(List treeList, List allCategoryEntityList) { + if (CollectionUtils.isEmpty(treeList)) { + return; + } + List parentIdList = treeList.stream().map(CategoryTreeVO::getValue).collect(Collectors.toList()); + List categoryEntityList = allCategoryEntityList.stream().filter(e -> parentIdList.contains(e.getParentId())).collect(Collectors.toList()); + Map> categorySubMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getParentId)); + treeList.forEach(e -> { + List childrenEntityList = categorySubMap.getOrDefault(e.getValue(), Lists.newArrayList()); + List childrenVOList = SmartBeanUtil.copyList(childrenEntityList, CategoryTreeVO.class); + childrenVOList.forEach(item -> { + item.setLabel(item.getCategoryName()); + item.setValue(item.getCategoryId()); + item.setCategoryFullName(e.getCategoryFullName() + StringConst.SEPARATOR_SLASH + item.getCategoryName()); + }); + // 递归查询 + this.queryAndSetSubCategory(childrenVOList, allCategoryEntityList); + e.setChildren(childrenVOList); + }); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java new file mode 100644 index 0000000..a04c2ea --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java @@ -0,0 +1,188 @@ +package net.lab1024.sa.admin.module.business.category.service; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategorySimpleDTO; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager; +import net.lab1024.sa.base.common.constant.StringConst; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 类目 查询 业务类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class CategoryQueryService { + + private static final Long DEFAULT_CATEGORY_PARENT_ID = 0L; + + @Resource + private CategoryCacheManager categoryCacheManager; + + /** + * 根据 id 查询未删除的类目 + * + * @param categoryId + * @return 可能 null + */ + public Optional queryCategory(Long categoryId) { + if (null == categoryId) { + return Optional.empty(); + } + CategoryEntity entity = categoryCacheManager.queryCategory(categoryId); + if (null == entity || entity.getDeletedFlag()) { + return Optional.empty(); + } + return Optional.of(entity); + } + + + /** + * 根据 类目id集合 查询未删除的类目集合 + */ + public Map queryCategoryList(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return Collections.emptyMap(); + } + categoryIdList = categoryIdList.stream().distinct().collect(Collectors.toList()); + Map categoryEntityMap = Maps.newHashMap(); + for (Long categoryId : categoryIdList) { + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (categoryEntity != null) { + categoryEntityMap.put(categoryId, categoryEntity); + } + } + return categoryEntityMap; + } + + + /** + * 根据类目id 递归查询该id的所有子类id 递归查询 + * 同时存入缓存 + * 注意:查询出来的集合 不包含传递的父类参数 + */ + public List queryCategorySubId(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return Collections.emptyList(); + } + //所有子类 + List categoryEntityList = Lists.newArrayList(); + categoryIdList.forEach(e -> { + categoryEntityList.addAll(categoryCacheManager.querySubCategory(e)); + }); + Map> subTypeMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getCategoryId)); + // 递归查询子类 + categoryIdList = subTypeMap.values().stream().flatMap(Collection::stream).map(CategoryEntity::getCategoryId).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(categoryIdList)) { + return Lists.newArrayList(); + } + categoryIdList.addAll(this.queryCategorySubId(categoryIdList)); + return categoryIdList; + } + + + /** + * 处理类目名称 + */ + public List queryCategoryName(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return null; + } + Map categoryMap = this.queryCategoryList(categoryIdList); + List categoryNameList = Lists.newArrayList(); + categoryIdList.forEach(e -> { + CategoryEntity categoryEntity = categoryMap.get(e); + if (categoryEntity != null) { + categoryNameList.add(categoryMap.get(e).getCategoryName()); + } + }); + return categoryNameList; + } + + /** + * 根据类目id 查询类目名称 + */ + public String queryCategoryName(Long categoryId) { + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (null == categoryEntity || categoryEntity.getDeletedFlag()) { + return null; + } + return categoryEntity.getCategoryName(); + } + + /** + * 根据类目id 查询类目详情 包含类目全称 如:医考/医师资格/临床执业 + */ + public CategorySimpleDTO queryCategoryInfo(Long categoryId) { + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (null == categoryEntity || categoryEntity.getDeletedFlag()) { + return null; + } + String fullName = this.queryFullName(categoryId); + // 返回DTO + CategorySimpleDTO categoryDTO = new CategorySimpleDTO(); + categoryDTO.setCategoryId(categoryId); + categoryDTO.setCategoryName(categoryEntity.getCategoryName()); + categoryDTO.setCategoryFullName(fullName); + categoryDTO.setParentId(categoryEntity.getParentId()); + return categoryDTO; + } + + /** + * 递归查询分类和所有父级类目 + * ps:特别注意返回的集合中 包含自己 + */ + public List queryCategoryAndParent(Long categoryId) { + List parentCategoryList = Lists.newArrayList(); + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (null == categoryEntity || categoryEntity.getDeletedFlag()) { + return parentCategoryList; + } + + // 父级始终放在第一位 + parentCategoryList.add(0, categoryEntity); + Long parentId = categoryEntity.getParentId(); + if (Objects.equals(DEFAULT_CATEGORY_PARENT_ID, parentId)) { + return parentCategoryList; + } + parentCategoryList.addAll(0, this.queryCategoryAndParent(parentId)); + return parentCategoryList; + } + + /** + * 查询 分类全称 如:医考/医师资格/临床执业 + */ + public String queryFullName(Long categoryId) { + List parentCategoryList = this.queryCategoryAndParent(categoryId); + // 拼接父级类目名称 斜杠分隔返回 + List nameList = parentCategoryList.stream().map(CategoryEntity::getCategoryName).collect(Collectors.toList()); + return StrUtil.join(StringConst.SEPARATOR_SLASH, nameList); + } + + /** + * 查询 分类全称 如:医考/医师资格/临床执业 + */ + public Map queryFullName(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return Maps.newHashMap(); + } + // 循环内查询的缓存 还ok + return categoryIdList.stream().collect(Collectors.toMap(Function.identity(), this::queryFullName)); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java new file mode 100644 index 0000000..74490d5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java @@ -0,0 +1,215 @@ +package net.lab1024.sa.admin.module.business.category.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.business.category.dao.CategoryDao; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategorySimpleDTO; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO; +import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.validation.constraints.NotBlank; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * 类目 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class CategoryService { + + @Resource + private CategoryDao categoryDao; + + @Resource + private CategoryQueryService categoryQueryService; + + @Resource + private CategoryCacheManager categoryCacheManager; + + /** + * 添加类目 + */ + public ResponseDTO add(CategoryAddForm addForm) { + // 校验类目 + CategoryEntity categoryEntity = SmartBeanUtil.copy(addForm, CategoryEntity.class); + ResponseDTO res = this.checkCategory(categoryEntity, false); + if (!res.getOk()) { + return res; + } + // 没有父类则使用默认父类 + Long parentId = null == addForm.getParentId() ? NumberUtils.LONG_ZERO : addForm.getParentId(); + categoryEntity.setParentId(parentId); + categoryEntity.setSort(null == addForm.getSort() ? 0 : addForm.getSort()); + categoryEntity.setDeletedFlag(false); + + // 保存数据 + categoryDao.insert(categoryEntity); + + // 更新缓存 + categoryCacheManager.removeCache(); + return ResponseDTO.ok(); + } + + /** + * 更新类目 + * 不能更新父级类目 + * + */ + public ResponseDTO update(CategoryUpdateForm updateForm) { + // 校验类目 + Long categoryId = updateForm.getCategoryId(); + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + CategoryEntity categoryEntity = SmartBeanUtil.copy(updateForm, CategoryEntity.class); + + /* + 不更新类目类型 + 不更新父类id + */ + Integer categoryType = optional.get().getCategoryType(); + categoryEntity.setCategoryType(categoryType); + categoryEntity.setParentId(optional.get().getParentId()); + + ResponseDTO responseDTO = this.checkCategory(categoryEntity, true); + if (!responseDTO.getOk()) { + return responseDTO; + } + categoryDao.updateById(categoryEntity); + + // 更新缓存 + categoryCacheManager.removeCache(); + return ResponseDTO.ok(); + } + + /** + * 新增/更新 类目时的 校验 + * + */ + private ResponseDTO checkCategory(CategoryEntity categoryEntity, boolean isUpdate) { + // 校验父级是否存在 + Long parentId = categoryEntity.getParentId(); + Integer categoryType = categoryEntity.getCategoryType(); + if (null != parentId) { + if (Objects.equals(categoryEntity.getCategoryId(), parentId)) { + return ResponseDTO.userErrorParam("父级类目怎么和自己相同了"); + } + if (!Objects.equals(parentId, NumberUtils.LONG_ZERO)) { + Optional optional = categoryQueryService.queryCategory(parentId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "父级类目不存在~"); + } + + CategoryEntity parent = optional.get(); + if (!Objects.equals(categoryType, parent.getCategoryType())) { + return ResponseDTO.userErrorParam("与父级类目类型不一致"); + } + } + + } else { + // 如果没有父类 使用默认父类 + parentId = NumberUtils.LONG_ZERO; + } + + // 校验同父类下 名称是否重复 + CategoryEntity queryEntity = new CategoryEntity(); + queryEntity.setParentId(parentId); + queryEntity.setCategoryType(categoryType); + queryEntity.setCategoryName(categoryEntity.getCategoryName()); + queryEntity.setDeletedFlag(false); + queryEntity = categoryDao.selectOne(queryEntity); + if (null != queryEntity) { + if (isUpdate) { + if (!Objects.equals(queryEntity.getCategoryId(), categoryEntity.getCategoryId())) { + return ResponseDTO.userErrorParam("同级下已存在相同类目~"); + } + } else { + return ResponseDTO.userErrorParam("同级下已存在相同类目~"); + } + } + return ResponseDTO.ok(); + } + + /** + * 查询 类目详情 + * + */ + public ResponseDTO queryDetail(Long categoryId) { + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + CategoryVO adminVO = SmartBeanUtil.copy(optional.get(), CategoryVO.class); + return ResponseDTO.ok(adminVO); + } + + /** + * 根据父级id 查询所有子类 返回层级树 + * 如果父类id 为空 返回所有类目层级 + * + */ + public ResponseDTO> queryTree(CategoryTreeQueryForm queryForm) { + if (null == queryForm.getParentId()) { + if (null == queryForm.getCategoryType()) { + return ResponseDTO.userErrorParam("类目类型不能为空"); + } + queryForm.setParentId(NumberUtils.LONG_ZERO); + } + List treeList = categoryCacheManager.queryCategoryTree(queryForm.getParentId(), queryForm.getCategoryType()); + return ResponseDTO.ok(treeList); + } + + /** + * 删除类目 + * 如果有未删除的子类 则无法删除 + * + */ + public ResponseDTO delete(Long categoryId) { + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + List categorySubId = categoryQueryService.queryCategorySubId(Lists.newArrayList(categoryId)); + if (CollectionUtils.isNotEmpty(categorySubId)) { + return ResponseDTO.userErrorParam("请先删除子级类目"); + } + + // 更新数据 + CategoryEntity categoryEntity = new CategoryEntity(); + categoryEntity.setCategoryId(categoryId); + categoryEntity.setDeletedFlag(true); + categoryDao.updateById(categoryEntity); + + // 更新缓存 + categoryCacheManager.removeCache(); + return ResponseDTO.ok(); + } + + public CategorySimpleDTO queryById(Long activityCategoryId) { + return categoryQueryService.queryCategoryInfo(activityCategoryId); + } + + public List getAllCategory() { + return categoryDao.selectList(null); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java new file mode 100644 index 0000000..95d37d5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.business.goods.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 商品状态 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum GoodsStatusEnum implements BaseEnum { + + /** + * 1 预约中 + */ + APPOINTMENT(1, "预约中"), + + /** + * 2 售卖 + */ + SELL(2, "售卖中"), + + /** + * 3 售罄 + */ + SELL_OUT(3, "售罄"), + + + ; + + private final Integer value; + + private final String desc; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java new file mode 100644 index 0000000..fe483e2 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.admin.module.business.goods.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO; +import net.lab1024.sa.admin.module.business.goods.service.GoodsService; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.base.common.util.SmartExcelUtil; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; + +/** + * 商品业务 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.Business.MANAGER_GOODS) +public class GoodsController { + + @Resource + private GoodsService goodsService; + + @Operation(summary = "分页查询 @author 胡克") + @PostMapping("/goods/query") + @SaCheckPermission("goods:query") + public ResponseDTO> query(@RequestBody @Valid GoodsQueryForm queryForm) { + return goodsService.query(queryForm); + } + + @Operation(summary = "添加商品 @author 胡克") + @PostMapping("/goods/add") + @SaCheckPermission("goods:add") + public ResponseDTO add(@RequestBody @Valid GoodsAddForm addForm) { + return goodsService.add(addForm); + } + + @Operation(summary = "更新商品 @author 胡克") + @PostMapping("/goods/update") + @SaCheckPermission("goods:update") + public ResponseDTO update(@RequestBody @Valid GoodsUpdateForm updateForm) { + return goodsService.update(updateForm); + } + + @Operation(summary = "删除 @author 卓大") + @GetMapping("/goods/delete/{goodsId}") + @SaCheckPermission("goods:delete") + public ResponseDTO delete(@PathVariable Long goodsId) { + return goodsService.delete(goodsId); + } + + @Operation(summary = "批量 @author 卓大") + @PostMapping("/goods/batchDelete") + @SaCheckPermission("goods:batchDelete") + public ResponseDTO batchDelete(@RequestBody @Valid ValidateList idList) { + return goodsService.batchDelete(idList); + } + + // --------------- 导出和导入 ------------------- + + @Operation(summary = "导入 @author 卓大") + @PostMapping("/goods/importGoods") + @SaCheckPermission("goods:importGoods") + public ResponseDTO importGoods(@RequestParam MultipartFile file) { + return goodsService.importGoods(file); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java new file mode 100644 index 0000000..8b5346d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.admin.module.business.goods.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 商品 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface GoodsDao extends BaseMapper { + + /** + * 分页 查询商品 + * + */ + List query(Page page, @Param("query") GoodsQueryForm query); + + /** + * 批量更新删除状态 + */ + + void batchUpdateDeleted(@Param("goodsIdList")List goodsIdList,@Param("deletedFlag")Boolean deletedFlag); + + GoodsEntity queryById(@Param("query") Long activityNameId); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java new file mode 100644 index 0000000..8ea568d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.module.business.goods.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 商品 实体类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_goods") +public class GoodsEntity { + + @TableId(type = IdType.AUTO) + private Long goodsId; + + /** + * 商品分类 + */ + private Long categoryId; + + /** + * 商品名称 + */ + private String goodsName; + + + /** + * 商品价格 + */ + private BigDecimal price; + + + /** + * 上架状态 + */ + private Boolean shelvesFlag; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java new file mode 100644 index 0000000..7317007 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 商品 添加表单 + */ +@Data +public class GoodsAddForm { + + @Schema(description = "商品分类") + @NotNull(message = "商品分类不能为空") + private Long categoryId; + + @Schema(description = "商品名称") + @NotBlank(message = "商品名称不能为空") + private String goodsName; + + @Schema(description = "商品价格") + @NotNull(message = "商品价格不能为空") + @DecimalMin(value = "0", message = "商品价格最低0") + private BigDecimal price; + + @Schema(description = "上架状态") + @NotNull(message = "上架状态不能为空") + private Boolean shelvesFlag; + + @Schema(description = "备注|可选") + private String remark; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.java new file mode 100644 index 0000000..4cbb4ca --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 商品 导入表单 + */ +@Data +public class GoodsImportForm { + + @ExcelProperty("商品分类") + private String categoryName; + + @ExcelProperty("商品名称") + private String goodsName; + + @ExcelProperty("商品价格") + private BigDecimal price; + + @ExcelProperty("备注") + private String remark; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java new file mode 100644 index 0000000..c8e11e5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +/** + * 商品 分页查询 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class GoodsQueryForm extends PageParam { + + @Schema(description = "商品分类") + private Integer categoryId; + + @Schema(description = "搜索词") + @Length(max = 30, message = "搜索词最多30字符") + private String searchWord; + + @Schema(description = "上架状态") + private Boolean shelvesFlag; + + @Schema(hidden = true) + private Boolean deletedFlag; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java new file mode 100644 index 0000000..600a22a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 商品 更新表单 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class GoodsUpdateForm extends GoodsAddForm { + + @Schema(description = "商品id") + @NotNull(message = "商品id不能为空") + private Long goodsId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.java new file mode 100644 index 0000000..60d2277 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.business.goods.domain.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * excel商品 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GoodsExcelVO { + + @ExcelProperty("商品分类") + private String categoryName; + + @ExcelProperty("商品名称") + private String goodsName; + + @ExcelProperty("商品状态错误") + private String goodsStatus; + + @ExcelProperty("产地") + private String place; + + @ExcelProperty("商品价格") + private BigDecimal price; + + @ExcelProperty("备注") + private String remark; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java new file mode 100644 index 0000000..5f9ae5c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.business.goods.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 商品 + */ +@Data +public class GoodsVO { + + @Schema(description = "商品分类") + private Long categoryId; + + @Schema(description = "商品名称") + private String goodsName; + + @SchemaEnum(GoodsStatusEnum.class) + private Integer goodsStatus; + + @Schema(description = "商品价格") + private BigDecimal price; + + @Schema(description = "上架状态") + private Boolean shelvesFlag; + + @Schema(description = "备注|可选") + private String remark; + + @Schema(description = "商品id") + private Long goodsId; + + @Schema(description = "商品分类") + private String categoryName; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java new file mode 100644 index 0000000..8ced63d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java @@ -0,0 +1,196 @@ +package net.lab1024.sa.admin.module.business.goods.service; + +import cn.idev.excel.FastExcel; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategorySimpleDTO; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.service.CategoryQueryService; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.admin.module.business.goods.dao.GoodsDao; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsImportForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.exception.BusinessException; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import net.lab1024.sa.base.module.support.dict.service.DictService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.validation.constraints.NotBlank; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 商品 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class GoodsService { + + @Resource + private GoodsDao goodsDao; + + @Resource + private CategoryQueryService categoryQueryService; + + @Resource + private DataTracerService dataTracerService; + + @Resource + private DictService dictService; + + public List getAllGoods() { + return goodsDao.selectList(null); + } + + /** + * 添加商品 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO add(GoodsAddForm addForm) { + // 商品校验 + ResponseDTO res = this.checkGoods(addForm); + if (!res.getOk()) { + return res; + } + GoodsEntity goodsEntity = SmartBeanUtil.copy(addForm, GoodsEntity.class); + goodsEntity.setDeletedFlag(Boolean.FALSE); + goodsDao.insert(goodsEntity); + dataTracerService.insert(goodsEntity.getGoodsId(), DataTracerTypeEnum.GOODS); + return ResponseDTO.ok(); + } + + /** + * 更新商品 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO update(GoodsUpdateForm updateForm) { + // 商品校验 + ResponseDTO res = this.checkGoods(updateForm); + if (!res.getOk()) { + return res; + } + GoodsEntity originEntity = goodsDao.selectById(updateForm.getGoodsId()); + GoodsEntity goodsEntity = SmartBeanUtil.copy(updateForm, GoodsEntity.class); + goodsDao.updateById(goodsEntity); + dataTracerService.update(updateForm.getGoodsId(), DataTracerTypeEnum.GOODS, originEntity, goodsEntity); + return ResponseDTO.ok(); + } + + /** + * 添加/更新 商品校验 + */ + private ResponseDTO checkGoods(GoodsAddForm addForm) { + // 校验类目id + Long categoryId = addForm.getCategoryId(); + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent() || !CategoryTypeEnum.GOODS.equalsValue(optional.get().getCategoryType())) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "商品类目不存在~"); + } + + return ResponseDTO.ok(); + } + + /** + * 删除 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long goodsId) { + GoodsEntity goodsEntity = goodsDao.selectById(goodsId); + if (goodsEntity == null) { + return ResponseDTO.userErrorParam("商品不存在"); + } + + batchDelete(Collections.singletonList(goodsId)); + dataTracerService.batchDelete(Collections.singletonList(goodsId), DataTracerTypeEnum.GOODS); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + */ + public ResponseDTO batchDelete(List goodsIdList) { + if (CollectionUtils.isEmpty(goodsIdList)) { + return ResponseDTO.ok(); + } + + goodsDao.batchUpdateDeleted(goodsIdList, Boolean.TRUE); + return ResponseDTO.ok(); + } + + + /** + * 分页查询 + */ + public ResponseDTO> query(GoodsQueryForm queryForm) { + queryForm.setDeletedFlag(false); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = goodsDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + if (pageResult.getEmptyFlag()) { + return ResponseDTO.ok(pageResult); + } + // 查询分类名称 + List categoryIdList = list.stream().map(GoodsVO::getCategoryId).distinct().collect(Collectors.toList()); + Map categoryMap = categoryQueryService.queryCategoryList(categoryIdList); + list.forEach(e -> { + CategoryEntity categoryEntity = categoryMap.get(e.getCategoryId()); + if (categoryEntity != null) { + e.setCategoryName(categoryEntity.getCategoryName()); + } + }); + return ResponseDTO.ok(pageResult); + } + + /** + * 商品导入 + * + * @param file 上传文件 + * @return 结果 + */ + public ResponseDTO importGoods(MultipartFile file) { + List dataList; + try { + dataList = FastExcel.read(file.getInputStream()).head(GoodsImportForm.class) + .sheet() + .doReadSync(); + } catch (IOException e) { + log.error(e.getMessage(), e); + throw new BusinessException("数据格式存在问题,无法读取"); + } + + if (CollectionUtils.isEmpty(dataList)) { + return ResponseDTO.userErrorParam("数据为空"); + } + + return ResponseDTO.okMsg("成功导入" + dataList.size() + "条,具体数据为:" + JSON.toJSONString(dataList)); + } + + public GoodsEntity queryById(Long activityNameId) { + return goodsDao.queryById(activityNameId); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/controller/BankController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/controller/BankController.java new file mode 100644 index 0000000..6b5b7a9 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/controller/BankController.java @@ -0,0 +1,82 @@ +package net.lab1024.sa.admin.module.business.oa.bank.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.bank.service.BankService; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankCreateForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankUpdateForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.Business.OA_BANK) +public class BankController { + + @Resource + private BankService bankService; + + @Operation(summary = "分页查询银行信息 @author 善逸") + @PostMapping("/oa/bank/page/query") + @SaCheckPermission("oa:bank:query") + public ResponseDTO> queryByPage(@RequestBody @Valid BankQueryForm queryForm) { + return bankService.queryByPage(queryForm); + } + + @Operation(summary = "根据企业ID查询银行信息列表 @author 善逸") + @GetMapping("/oa/bank/query/list/{enterpriseId}") + @SaCheckPermission("oa:bank:query") + public ResponseDTO> queryList(@PathVariable Long enterpriseId) { + return bankService.queryList(enterpriseId); + } + + @Operation(summary = "查询银行信息详情 @author 善逸") + @GetMapping("/oa/bank/get/{bankId}") + @SaCheckPermission("oa:bank:query") + public ResponseDTO getDetail(@PathVariable Long bankId) { + return bankService.getDetail(bankId); + } + + @Operation(summary = "新建银行信息 @author 善逸") + @PostMapping("/oa/bank/create") + @SaCheckPermission("oa:bank:add") + public ResponseDTO createBank(@RequestBody @Valid BankCreateForm createVO) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + createVO.setCreateUserId(requestUser.getUserId()); + createVO.setCreateUserName(requestUser.getUserName()); + return bankService.createBank(createVO); + } + + @Operation(summary = "编辑银行信息 @author 善逸") + @PostMapping("/oa/bank/update") + @SaCheckPermission("oa:bank:update") + public ResponseDTO updateBank(@RequestBody @Valid BankUpdateForm updateVO) { + return bankService.updateBank(updateVO); + } + + @Operation(summary = "删除银行信息 @author 善逸") + @GetMapping("/oa/bank/delete/{bankId}") + @SaCheckPermission("oa:bank:delete") + public ResponseDTO deleteBank(@PathVariable Long bankId) { + return bankService.deleteBank(bankId); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/dao/BankDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/dao/BankDao.java new file mode 100644 index 0000000..0a058d1 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/dao/BankDao.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.business.oa.bank.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankEntity; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface BankDao extends BaseMapper { + + /** + * 根据账号查询 + */ + BankEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeBankId") Long excludeBankId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 删除银行信息 + * + */ + void deleteBank(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 银行信息分页查询 + * + */ + List queryPage(Page page, @Param("queryForm") BankQueryForm queryForm); + + /** + * 查询银行信息详情 + */ + BankVO getDetail(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java new file mode 100644 index 0000000..eaa7b98 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * OA办公-银行信息新建 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class BankCreateForm { + + @Schema(description = "开户银行") + @NotBlank(message = "开户银行不能为空") + @Length(max = 200, message = "开户银行最多200字符") + private String bankName; + + @Schema(description = "账户名称") + @NotBlank(message = "账户名称不能为空") + @Length(max = 200, message = "账户名称最多200字符") + private String accountName; + + @Schema(description = "账号") + @NotBlank(message = "账号不能为空") + @Length(max = 200, message = "账号最多200字符") + private String accountNumber; + + @Schema(description = "备注") + @Length(max = 500, message = "备注最多500字符") + private String remark; + + @Schema(description = "是否对公") + @NotNull(message = "是否对公不能为空") + private Boolean businessFlag; + + @Schema(description = "企业") + @NotNull(message = "企业不能为空") + private Long enterpriseId; + + @Schema(description = "禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @Schema(hidden = true) + private Long createUserId; + + @Schema(hidden = true) + private String createUserName; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java new file mode 100644 index 0000000..a9f0a06 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel; + +import java.time.LocalDateTime; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_oa_bank") +public class BankEntity { + + /** + * 银行信息ID + */ + @TableId(type = IdType.AUTO) + @DataTracerFieldLabel("银行信息ID") + private Long bankId; + + /** + * 开户银行 + */ + @DataTracerFieldLabel("开户银行") + private String bankName; + + /** + * 账户名称 + */ + @DataTracerFieldLabel("账户名称") + private String accountName; + + /** + * 账号 + */ + @DataTracerFieldLabel("账号") + private String accountNumber; + + /** + * 备注 + */ + @DataTracerFieldLabel("备注") + private String remark; + + /** + * 是否对公 + */ + @DataTracerFieldLabel("是否对公") + private Boolean businessFlag; + + /** + * 企业ID + */ + private Long enterpriseId; + + /** + * 禁用状态 + */ + @DataTracerFieldLabel("禁用状态") + private Boolean disabledFlag; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人ID + */ + private String createUserName; + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java new file mode 100644 index 0000000..53a405c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * OA办公-OA银行信息查询 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class BankQueryForm extends PageParam { + + @Schema(description = "企业ID") + private Long enterpriseId; + + @Schema(description = "关键字") + @Length(max = 200, message = "关键字最多200字符") + private String keywords; + + @Schema(description = "开始时间") + private LocalDate startTime; + + @Schema(description = "结束时间") + private LocalDate endTime; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "删除状态", hidden = true) + private Boolean deletedFlag; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java new file mode 100644 index 0000000..74dca2a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * OA办公-银行信息更新 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class BankUpdateForm extends BankCreateForm { + + @Schema(description = "银行信息ID") + @NotNull(message = "银行信息ID不能为空") + private Long bankId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java new file mode 100644 index 0000000..d263f38 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class BankVO { + + @Schema(description = "银行信息ID") + private Long bankId; + + @Schema(description = "开户银行") + private String bankName; + + @Schema(description = "账户名称") + private String accountName; + + @Schema(description = "账号") + private String accountNumber; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "是否对公") + private Boolean businessFlag; + + @Schema(description = "企业ID") + private Long enterpriseId; + + @Schema(description = "企业名称") + private String enterpriseName; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "创建人ID") + private Long createUserId; + + @Schema(description = "创建人名称") + private String createUserName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/service/BankService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/service/BankService.java new file mode 100644 index 0000000..bf688dd --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/service/BankService.java @@ -0,0 +1,146 @@ +package net.lab1024.sa.admin.module.business.oa.bank.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.oa.bank.dao.BankDao; +import net.lab1024.sa.admin.module.business.oa.bank.domain.*; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class BankService { + + @Resource + private BankDao bankDao; + + @Resource + private EnterpriseDao enterpriseDao; + + @Resource + private DataTracerService dataTracerService; + + /** + * 分页查询银行信息 + */ + public ResponseDTO> queryByPage(BankQueryForm queryForm) { + queryForm.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List bankList = bankDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, bankList); + return ResponseDTO.ok(pageResult); + } + + /** + * 根据企业ID查询不分页的银行列表 + */ + public ResponseDTO> queryList(Long enterpriseId) { + BankQueryForm queryForm = new BankQueryForm(); + queryForm.setEnterpriseId(enterpriseId); + queryForm.setDeletedFlag(Boolean.FALSE); + List bankList = bankDao.queryPage(null, queryForm); + return ResponseDTO.ok(bankList); + } + + /** + * 查询银行信息详情 + */ + public ResponseDTO getDetail(Long bankId) { + // 校验银行信息是否存在 + BankVO bankVO = bankDao.getDetail(bankId, Boolean.FALSE); + if (Objects.isNull(bankVO)) { + return ResponseDTO.userErrorParam("银行信息不存在"); + } + return ResponseDTO.ok(bankVO); + } + + /** + * 新建银行信息 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createBank(BankCreateForm createVO) { + Long enterpriseId = createVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + // 验证银行信息账号是否重复 + BankEntity validateBank = bankDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE); + if (Objects.nonNull(validateBank)) { + return ResponseDTO.userErrorParam("银行信息账号重复"); + } + // 数据插入 + BankEntity insertBank = SmartBeanUtil.copy(createVO, BankEntity.class); + bankDao.insert(insertBank); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertBank)); + return ResponseDTO.ok(); + } + + /** + * 编辑银行信息 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateBank(BankUpdateForm updateVO) { + Long enterpriseId = updateVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + Long bankId = updateVO.getBankId(); + // 校验银行信息是否存在 + BankEntity bankDetail = bankDao.selectById(bankId); + if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("银行信息不存在"); + } + // 验证银行信息账号是否重复 + BankEntity validateBank = bankDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), bankId, Boolean.FALSE); + if (Objects.nonNull(validateBank)) { + return ResponseDTO.userErrorParam("银行信息账号重复"); + } + // 数据编辑 + BankEntity updateBank = SmartBeanUtil.copy(updateVO, BankEntity.class); + bankDao.updateById(updateBank); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail, updateBank)); + return ResponseDTO.ok(); + } + + + /** + * 删除银行信息 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteBank(Long bankId) { + // 校验银行信息是否存在 + BankEntity bankDetail = bankDao.selectById(bankId); + if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("银行信息不存在"); + } + bankDao.deleteBank(bankId, Boolean.TRUE); + dataTracerService.addTrace(bankDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail)); + return ResponseDTO.ok(); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java new file mode 100644 index 0000000..9603355 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.constant; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 企业类型 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum EnterpriseTypeEnum implements BaseEnum { + + /** + * 有限企业 + */ + NORMAL(1, "有限企业"), + + /** + * 外资企业 + */ + FOREIGN(2, "外资企业"), + ; + + private Integer value; + private String desc; + + EnterpriseTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/controller/EnterpriseController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/controller/EnterpriseController.java new file mode 100644 index 0000000..a62ddc9 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/controller/EnterpriseController.java @@ -0,0 +1,132 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.enterprise.service.EnterpriseService; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.admin.util.AdminRequestUtil; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.*; +import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 企业 + */ +@Slf4j +@RestController +@Tag(name = AdminSwaggerTagConst.Business.OA_ENTERPRISE) +@OperateLog +public class EnterpriseController { + + @Resource + private EnterpriseService enterpriseService; + + @Operation(summary = "分页查询企业模块 @author 开云") + @PostMapping("/oa/enterprise/page/query") + @SaCheckPermission("oa:enterprise:query") + public ResponseDTO> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryForm) { + return enterpriseService.queryByPage(queryForm); + } + + @Operation(summary = "导出企业信息 @author 卓大") + @PostMapping("/oa/enterprise/exportExcel") + public void exportExcel(@RequestBody @Valid EnterpriseQueryForm queryForm, HttpServletResponse response) throws IOException { + List data = enterpriseService.getExcelExportData(queryForm); + if (CollectionUtils.isEmpty(data)) { + SmartResponseUtil.write(response, ResponseDTO.userErrorParam("暂无数据")); + return; + } + + String watermark = AdminRequestUtil.getRequestUser().getActualName(); + watermark += SmartLocalDateUtil.format(LocalDateTime.now(), SmartDateFormatterEnum.YMD_HMS); + + SmartExcelUtil.exportExcelWithWatermark(response,"企业基本信息.xlsx","企业信息",EnterpriseExcelVO.class,data,watermark); + + } + + @Operation(summary = "查询企业详情 @author 开云") + @GetMapping("/oa/enterprise/get/{enterpriseId}") + @SaCheckPermission("oa:enterprise:detail") + public ResponseDTO getDetail(@PathVariable Long enterpriseId) { + return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId)); + } + + @Operation(summary = "新建企业 @author 开云") + @PostMapping("/oa/enterprise/create") + @SaCheckPermission("oa:enterprise:add") + public ResponseDTO createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + createVO.setCreateUserId(requestUser.getUserId()); + createVO.setCreateUserName(requestUser.getUserName()); + return enterpriseService.createEnterprise(createVO); + } + + @Operation(summary = "编辑企业 @author 开云") + @PostMapping("/oa/enterprise/update") + @SaCheckPermission("oa:enterprise:update") + public ResponseDTO updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) { + return enterpriseService.updateEnterprise(updateVO); + } + + @Operation(summary = "删除企业 @author 开云") + @GetMapping("/oa/enterprise/delete/{enterpriseId}") + @SaCheckPermission("oa:enterprise:delete") + public ResponseDTO deleteEnterprise(@PathVariable Long enterpriseId) { + return enterpriseService.deleteEnterprise(enterpriseId); + } + + @Operation(summary = "按照类型查询企业 @author 开云") + @GetMapping("/oa/enterprise/query/list") + @SaCheckPermission("oa:enterprise:query") + public ResponseDTO> queryList(@RequestParam(value = "type", required = false) Integer type) { + return enterpriseService.queryList(type); + } + + + @Operation(summary = "企业添加员工 @author 罗伊") + @PostMapping("/oa/enterprise/employee/add") + @SaCheckPermission("oa:enterprise:addEmployee") + public ResponseDTO addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) { + return enterpriseService.addEmployee(enterpriseEmployeeForm); + } + + @Operation(summary = "查询企业全部员工 @author 罗伊") + @PostMapping("/oa/enterprise/employee/list") + @SaCheckPermission("oa:enterprise:queryEmployee") + public ResponseDTO> employeeList(@RequestBody @Valid List enterpriseIdList) { + return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList)); + } + + @Operation(summary = "分页查询企业员工 @author 卓大") + @PostMapping("/oa/enterprise/employee/queryPage") + @SaCheckPermission("oa:enterprise:queryEmployee") + public ResponseDTO> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) { + return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm)); + } + + + @Operation(summary = "企业删除员工 @author 罗伊") + @PostMapping("/oa/enterprise/employee/delete") + @SaCheckPermission("oa:enterprise:deleteEmployee") + public ResponseDTO deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) { + return enterpriseService.deleteEmployee(enterpriseEmployeeForm); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java new file mode 100644 index 0000000..bde9499 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java @@ -0,0 +1,64 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseQueryForm; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface EnterpriseDao extends BaseMapper { + + /** + * 根据企业名称查询 + * + */ + EnterpriseEntity queryByEnterpriseName(@Param("enterpriseName") String enterpriseName, @Param("excludeEnterpriseId") Long excludeEnterpriseId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 删除企业 + */ + void deleteEnterprise(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 企业分页查询 + * + */ + List queryPage(Page page, @Param("queryForm") EnterpriseQueryForm queryForm); + + /** + * 查询导出的数据 + * + */ + List selectExcelExportData(@Param("queryForm") EnterpriseQueryForm queryForm); + + /** + * 查询企业详情 + * + */ + EnterpriseVO getDetail(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询列表 + * + */ + List queryList(@Param("type") Integer type, @Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag); + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java new file mode 100644 index 0000000..e73a493 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java @@ -0,0 +1,69 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseEmployeeQueryForm; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 企业员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface EnterpriseEmployeeDao extends BaseMapper { + + + /** + * 根据员工查询 + */ + List selectByEmployeeIdList(@Param("employeeIdList")Collection employeeIdList); + + /** + * 查询员工关联的企业 + */ + List selectEnterpriseIdByEmployeeId(@Param("employeeId")Long employeeId); + /** + * 根据企业查询 + */ + List selectByEnterpriseIdList(@Param("enterpriseIdList")Collection enterpriseIdList); + /** + * 根据企业查询 + */ + List selectByEnterpriseId(@Param("enterpriseId")Long enterpriseId); + + /** + * 查询企业下的所有员工id + */ + List selectEmployeeIdByEnterpriseIdList(@Param("enterpriseIdList")Collection enterpriseIdList); + /** + * 根据员工删除 + */ + void deleteByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection employeeIdList); + + /** + * 根据员工查询 + */ + List selectByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection employeeIdList); + + /** + * 删除某员工关联的所有企业 + */ + void deleteByEmployeeId(@Param("employeeId")Long employeeId); + + /** + * 分页查询企业员工 + */ + List queryPageEmployeeList(Page page,@Param("queryForm") EnterpriseEmployeeQueryForm queryForm); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java new file mode 100644 index 0000000..a252e66 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 企业员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_oa_enterprise_employee") +@NoArgsConstructor +public class EnterpriseEmployeeEntity { + + @TableId(type = IdType.AUTO) + private Long enterpriseEmployeeId; + + /** + * 企业ID + */ + private Long enterpriseId; + /** + * 员工 + */ + private Long employeeId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public EnterpriseEmployeeEntity(Long enterpriseId, Long employeeId) { + this.enterpriseId = enterpriseId; + this.employeeId = employeeId; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java new file mode 100644 index 0000000..6bbbf67 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java @@ -0,0 +1,153 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldEnum; +import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel; + +import java.time.LocalDateTime; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_oa_enterprise") +public class EnterpriseEntity { + + /** + * 企业ID + */ + @TableId(type = IdType.AUTO) + private Long enterpriseId; + + /** + * 企业名称 + */ + @DataTracerFieldLabel("企业名称") + private String enterpriseName; + + /** + * 企业logo + */ + @DataTracerFieldLabel("企业logo") + private String enterpriseLogo; + + /** + * 统一社会信用代码 + */ + @DataTracerFieldLabel("统一社会信用代码") + private String unifiedSocialCreditCode; + + /** + * 类型 + * + * @see EnterpriseTypeEnum + */ + @DataTracerFieldLabel("类型") + @DataTracerFieldEnum(enumClass = EnterpriseTypeEnum.class) + private Integer type; + + /** + * 联系人 + */ + @DataTracerFieldLabel("联系人") + private String contact; + + /** + * 联系人电话 + */ + @DataTracerFieldLabel("联系人电话") + private String contactPhone; + + /** + * 邮箱 + */ + @DataTracerFieldLabel("邮箱") + private String email; + + /** + * 省份 + */ + private Integer province; + + /** + * 省份名称 + */ + @DataTracerFieldLabel("省份名称") + private String provinceName; + + /** + * 城市 + */ + private Integer city; + + /** + * 城市名称 + */ + @DataTracerFieldLabel("城市名称") + private String cityName; + + /** + * 区县 + */ + private Integer district; + + /** + * 区县名称 + */ + @DataTracerFieldLabel("区县名称") + private String districtName; + + /** + * 详细地址 + */ + @DataTracerFieldLabel("详细地址") + private String address; + + /** + * 营业执照 + */ + @DataTracerFieldLabel("营业执照") + private String businessLicense; + + /** + * 禁用状态 + */ + @DataTracerFieldLabel("禁用状态") + private Boolean disabledFlag; + + /** + * 删除状态 + */ + @DataTracerFieldLabel("删除状态") + private Boolean deletedFlag; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人ID + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java new file mode 100644 index 0000000..b1451e2 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java @@ -0,0 +1,101 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum; +import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.util.SmartVerificationUtil; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * OA企业模块创建 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseCreateForm { + + @Schema(description = "企业名称") + @NotBlank(message = "企业名称不能为空") + @Length(max = 200, message = "企业名称最多200字符") + private String enterpriseName; + + @Schema(description = "企业logo") + @JsonSerialize(using = FileKeyVoSerializer.class) + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String enterpriseLogo; + + @Schema(description = "统一社会信用代码") + @NotBlank(message = "统一社会信用代码不能为空") + @Length(max = 200, message = "统一社会信用代码最多200字符") + private String unifiedSocialCreditCode; + + @Schema(description = "联系人") + @NotBlank(message = "联系人不能为空") + @Length(max = 100, message = "联系人最多100字符") + private String contact; + + @Schema(description = "联系人电话") + @NotBlank(message = "联系人电话不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String contactPhone; + + @SchemaEnum(desc = "类型", value = EnterpriseTypeEnum.class) + @CheckEnum(message = "类型不正确", value = EnterpriseTypeEnum.class) + private Integer type; + + @Schema(description = "邮箱") + @Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱格式不正确") + private String email; + + @Schema(description = "省份") + private Integer province; + + @Schema(description = "省份名称") + private String provinceName; + + @Schema(description = "城市") + private Integer city; + + @Schema(description = "城市名称") + private String cityName; + + @Schema(description = "区县") + private Integer district; + + @Schema(description = "区县名称") + private String districtName; + + @Schema(description = "详细地址") + @Length(max = 500, message = "详细地址最多500字符") + private String address; + + @Schema(description = "营业执照") + @JsonSerialize(using = FileKeyVoSerializer.class) + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String businessLicense; + + @Schema(description = "禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @Schema(description = "创建人", hidden = true) + private Long createUserId; + + @Schema(description = "创建人", hidden = true) + private String createUserName; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java new file mode 100644 index 0000000..a9d3ed0 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 企业员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseEmployeeForm { + + @Schema(description = "企业id") + @NotNull(message = "企业id不能为空") + private Long enterpriseId; + + @Schema(description = "员工信息id") + @NotEmpty(message = "员工信息id不能为空") + private List employeeIdList; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java new file mode 100644 index 0000000..880b2ae --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 查询企业员工 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseEmployeeQueryForm extends PageParam { + + @Schema(description = "搜索词") + @Length(max = 20, message = "搜索词最多20字符") + private String keyword; + + @Schema(description = "公司Id") + @NotNull(message = "公司id 不能为空") + private Long enterpriseId; + + @Schema(description = "删除标识", hidden = true) + private Boolean deletedFlag; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java new file mode 100644 index 0000000..7891508 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * OA企业模块分页查询 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseQueryForm extends PageParam { + + @Schema(description = "关键字") + @Length(max = 200, message = "关键字最多200字符") + private String keywords; + + @Schema(description = "开始时间") + private LocalDate startTime; + + @Schema(description = "结束时间") + private LocalDate endTime; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "删除状态", hidden = true) + private Boolean deletedFlag; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java new file mode 100644 index 0000000..1aa980f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * OA企业模块编辑 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseUpdateForm extends EnterpriseCreateForm { + + @Schema(description = "企业ID") + @NotNull(message = "企业ID不能为空") + private Long enterpriseId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java new file mode 100644 index 0000000..18aa205 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 企业员工信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseEmployeeVO { + + private Long enterpriseEmployeeId; + + @Schema(description = "企业ID") + private Long enterpriseId; + + @Schema(description = "企业名称") + private String enterpriseName; + + @Schema(description = "员工") + private Long employeeId; + + @Schema(description = "登录账号") + private String loginName; + + @Schema(description = "员工名称") + private String actualName; + + @Schema(description = "手机号码") + private String phone; + + @Schema(description = "部门id") + private Long departmentId; + + @Schema(description = "是否被禁用") + private Boolean disabledFlag; + + @Schema(description = "部门名称") + private String departmentName; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.java new file mode 100644 index 0000000..8b9c838 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.Data; + +/** + * 企业信息 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseExcelVO { + + @ExcelProperty("企业名称") + private String enterpriseName; + + @ExcelProperty("统一社会信用代码") + private String unifiedSocialCreditCode; + + @ExcelProperty("企业类型") + private String typeName; + + @ExcelProperty("联系人") + private String contact; + + @ExcelProperty("联系人电话") + private String contactPhone; + + @ExcelProperty("邮箱") + private String email; + + @ExcelProperty("省份名称") + private String provinceName; + + @ExcelProperty("城市名称") + private String cityName; + + @ExcelProperty("区县名称") + private String districtName; + + @ExcelProperty("详细地址") + private String address; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java new file mode 100644 index 0000000..1320292 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * OA企业模块列表 + * + * @author lihaifan + * @date 2022/6/23 14:31 + */ +@Data +public class EnterpriseListVO { + + @Schema(description = "企业ID") + private Long enterpriseId; + + @Schema(description = "企业名称") + private String enterpriseName; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java new file mode 100644 index 0000000..54d9b47 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java @@ -0,0 +1,89 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.time.LocalDateTime; + +/** + * 企业信息 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class EnterpriseVO { + + @Schema(description = "企业ID") + private Long enterpriseId; + + @Schema(description = "企业名称") + private String enterpriseName; + + @Schema(description = "企业logo") + @JsonSerialize(using = FileKeyVoSerializer.class) + private String enterpriseLogo; + + @Schema(description = "统一社会信用代码") + private String unifiedSocialCreditCode; + + @SchemaEnum(desc = "类型", value = EnterpriseTypeEnum.class) + private Integer type; + + @Schema(description = "联系人") + private String contact; + + @Schema(description = "联系人电话") + private String contactPhone; + + @Schema(description = "邮箱") + private String email; + + @Schema(description = "省份") + private Integer province; + + @Schema(description = "省份名称") + private String provinceName; + + @Schema(description = "城市") + private Integer city; + + @Schema(description = "城市名称") + private String cityName; + + @Schema(description = "区县") + private Integer district; + + @Schema(description = "区县名称") + private String districtName; + + @Schema(description = "详细地址") + private String address; + + @Schema(description = "营业执照") + @JsonSerialize(using = FileKeyVoSerializer.class) + private String businessLicense; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "创建人ID") + private Long createUserId; + + @Schema(description = "创建人名称") + private String createUserName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/manager/EnterpriseEmployeeManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/manager/EnterpriseEmployeeManager.java new file mode 100644 index 0000000..a3c21d8 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/manager/EnterpriseEmployeeManager.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity; +import org.springframework.stereotype.Service; + +/** + * 企业员工关系 manager + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class EnterpriseEmployeeManager extends ServiceImpl { +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/service/EnterpriseService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/service/EnterpriseService.java new file mode 100644 index 0000000..2b97a6b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/service/EnterpriseService.java @@ -0,0 +1,239 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.manager.EnterpriseEmployeeManager; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerForm; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class EnterpriseService { + + @Resource + private EnterpriseDao enterpriseDao; + + @Resource + private EnterpriseEmployeeDao enterpriseEmployeeDao; + + @Resource + private EnterpriseEmployeeManager enterpriseEmployeeManager; + + @Resource + private DataTracerService dataTracerService; + + @Resource + private DepartmentService departmentService; + + /** + * 分页查询企业模块 + * + */ + public ResponseDTO> queryByPage(EnterpriseQueryForm queryForm) { + queryForm.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List enterpriseList = enterpriseDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, enterpriseList); + return ResponseDTO.ok(pageResult); + } + + /** + * 获取导出数据 + */ + public List getExcelExportData(EnterpriseQueryForm queryForm) { + queryForm.setDeletedFlag(false); + return enterpriseDao.selectExcelExportData(queryForm); + } + + /** + * 查询企业详情 + * + */ + public EnterpriseVO getDetail(Long enterpriseId) { + return enterpriseDao.getDetail(enterpriseId, Boolean.FALSE); + } + + /** + * 新建企业 + * + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createEnterprise(EnterpriseCreateForm createVO) { + // 验证企业名称是否重复 + EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(createVO.getEnterpriseName(), null, Boolean.FALSE); + if (Objects.nonNull(validateEnterprise)) { + return ResponseDTO.userErrorParam("企业名称重复"); + } + // 数据插入 + EnterpriseEntity insertEnterprise = SmartBeanUtil.copy(createVO, EnterpriseEntity.class); + enterpriseDao.insert(insertEnterprise); + dataTracerService.insert(insertEnterprise.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE); + return ResponseDTO.ok(); + } + + /** + * 编辑企业 + * + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateEnterprise(EnterpriseUpdateForm updateVO) { + Long enterpriseId = updateVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + // 验证企业名称是否重复 + EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(updateVO.getEnterpriseName(), enterpriseId, Boolean.FALSE); + if (Objects.nonNull(validateEnterprise)) { + return ResponseDTO.userErrorParam("企业名称重复"); + } + // 数据编辑 + EnterpriseEntity updateEntity = SmartBeanUtil.copy(enterpriseDetail, EnterpriseEntity.class); + SmartBeanUtil.copyProperties(updateVO, updateEntity); + enterpriseDao.updateById(updateEntity); + + //变更记录 + DataTracerForm dataTracerForm = DataTracerForm.builder() + .dataId(updateVO.getEnterpriseId()) + .type(DataTracerTypeEnum.OA_ENTERPRISE) + .content("修改企业信息") + .diffOld(dataTracerService.getChangeContent(enterpriseDetail)) + .diffNew(dataTracerService.getChangeContent(updateEntity)) + .build(); + + dataTracerService.addTrace(dataTracerForm); + return ResponseDTO.ok(); + } + + + /** + * 删除企业 + * + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteEnterprise(Long enterpriseId) { + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + enterpriseDao.deleteEnterprise(enterpriseId, Boolean.TRUE); + dataTracerService.delete(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE); + return ResponseDTO.ok(); + } + + /** + * 企业列表查询 + */ + public ResponseDTO> queryList(Integer type) { + List enterpriseList = enterpriseDao.queryList(type, Boolean.FALSE, Boolean.FALSE); + return ResponseDTO.ok(enterpriseList); + } + + //----------------------------------------- 以下为员工相关-------------------------------------------- + + /** + * 企业添加员工 + * + */ + public synchronized ResponseDTO addEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) { + Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId(); + EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId); + if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + //过滤掉已存在的员工 + List waitAddEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList(); + List enterpriseEmployeeEntityList = enterpriseEmployeeDao.selectByEnterpriseAndEmployeeIdList(enterpriseId, waitAddEmployeeIdList); + if (CollectionUtils.isNotEmpty(enterpriseEmployeeEntityList)) { + List existEmployeeIdList = enterpriseEmployeeEntityList.stream().map(EnterpriseEmployeeEntity::getEmployeeId).collect(Collectors.toList()); + waitAddEmployeeIdList = waitAddEmployeeIdList.stream().filter(e -> !existEmployeeIdList.contains(e)).collect(Collectors.toList()); + } + if (CollectionUtils.isEmpty(waitAddEmployeeIdList)) { + return ResponseDTO.ok(); + } + List batchAddList = Lists.newArrayList(); + for (Long employeeId : waitAddEmployeeIdList) { + EnterpriseEmployeeEntity enterpriseEmployeeEntity = new EnterpriseEmployeeEntity(); + enterpriseEmployeeEntity.setEnterpriseId(enterpriseId); + enterpriseEmployeeEntity.setEmployeeId(employeeId); + batchAddList.add(enterpriseEmployeeEntity); + } + enterpriseEmployeeManager.saveBatch(batchAddList); + return ResponseDTO.ok(); + } + + /** + * 企业删除员工 + * + */ + public synchronized ResponseDTO deleteEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) { + Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId(); + EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId); + if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + List waitDeleteEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList(); + enterpriseEmployeeDao.deleteByEnterpriseAndEmployeeIdList(enterpriseId, waitDeleteEmployeeIdList); + return ResponseDTO.ok(); + } + + /** + * 企业下员工列表 + * + */ + public List employeeList(List enterpriseIdList) { + if (CollectionUtils.isEmpty(enterpriseIdList)) { + return Lists.newArrayList(); + } + return enterpriseEmployeeDao.selectByEnterpriseIdList(enterpriseIdList); + } + + /** + * 分页查询企业员工 + * + */ + public PageResult queryPageEmployeeList(EnterpriseEmployeeQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List enterpriseEmployeeVOList = enterpriseEmployeeDao.queryPageEmployeeList(page, queryForm); + for (EnterpriseEmployeeVO enterpriseEmployeeVO : enterpriseEmployeeVOList) { + enterpriseEmployeeVO.setDepartmentName(departmentService.getDepartmentPath(enterpriseEmployeeVO.getDepartmentId())); + } + return SmartPageUtil.convert2PageResult(page, enterpriseEmployeeVOList); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/controller/InvoiceController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/controller/InvoiceController.java new file mode 100644 index 0000000..1515697 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/controller/InvoiceController.java @@ -0,0 +1,88 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.invoice.service.InvoiceService; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceAddForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceUpdateForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@RestController +@Tag(name = AdminSwaggerTagConst.Business.OA_INVOICE) +public class InvoiceController { + + @Resource + private InvoiceService invoiceService; + + @Operation(summary = "分页查询发票信息 @author 善逸") + @PostMapping("/oa/invoice/page/query") + @SaCheckPermission("oa:invoice:query") + public ResponseDTO> queryByPage(@RequestBody @Valid InvoiceQueryForm queryForm) { + return invoiceService.queryByPage(queryForm); + } + + @Operation(summary = "查询发票信息详情 @author 善逸") + @GetMapping("/oa/invoice/get/{invoiceId}") + @SaCheckPermission("oa:invoice:query") + public ResponseDTO getDetail(@PathVariable Long invoiceId) { + return invoiceService.getDetail(invoiceId); + } + + @Operation(summary = "新建发票信息 @author 善逸") + @PostMapping("/oa/invoice/create") + @SaCheckPermission("oa:invoice:add") + public ResponseDTO createInvoice(@RequestBody @Valid InvoiceAddForm createVO) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + createVO.setCreateUserId(requestUser.getUserId()); + createVO.setCreateUserName(requestUser.getUserName()); + return invoiceService.createInvoice(createVO); + } + + @OperateLog + @Operation(summary = "编辑发票信息 @author 善逸") + @PostMapping("/oa/invoice/update") + @SaCheckPermission("oa:invoice:update") + public ResponseDTO updateInvoice(@RequestBody @Valid InvoiceUpdateForm updateVO) { + return invoiceService.updateInvoice(updateVO); + } + + @Operation(summary = "删除发票信息 @author 善逸") + @GetMapping("/invoice/delete/{invoiceId}") + @SaCheckPermission("oa:invoice:delete") + public ResponseDTO deleteInvoice(@PathVariable Long invoiceId) { + return invoiceService.deleteInvoice(invoiceId); + } + + @Operation(summary = "查询列表 @author lidoudou") + @GetMapping("/oa/invoice/query/list/{enterpriseId}") + @SaCheckPermission("oa:invoice:query") + public ResponseDTO> queryList(@PathVariable Long enterpriseId) { + return invoiceService.queryList(enterpriseId); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/dao/InvoiceDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/dao/InvoiceDao.java new file mode 100644 index 0000000..5afcebb --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/dao/InvoiceDao.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceEntity; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface InvoiceDao extends BaseMapper { + + /** + * 根据账号查询 + * @param enterpriseId + * @param accountNumber + * @param excludeInvoiceId + * @param deletedFlag + * @return + */ + InvoiceEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeInvoiceId") Long excludeInvoiceId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 删除发票信息 + * + * @param invoiceId + * @param deletedFlag + */ + void deleteInvoice(@Param("invoiceId") Long invoiceId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 发票信息分页查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") InvoiceQueryForm queryForm); + + /** + * 查询发票信息详情 + * @param invoiceId + * @param deletedFlag + * @return + */ + InvoiceVO getDetail(@Param("invoiceId") Long invoiceId, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java new file mode 100644 index 0000000..3dd670c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * OA发票信息新建 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class InvoiceAddForm { + + @Schema(description = "开票抬头") + @NotBlank(message = "开票抬头不能为空") + @Length(max = 200, message = "开票抬头最多200字符") + private String invoiceHeads; + + @Schema(description = "纳税人识别号") + @NotBlank(message = "纳税人识别号不能为空") + @Length(max = 200, message = "纳税人识别号最多200字符") + private String taxpayerIdentificationNumber; + + @Schema(description = "银行账户") + @NotBlank(message = "银行账户不能为空") + @Length(max = 200, message = "银行账户最多200字符") + private String accountNumber; + + @Schema(description = "开户行") + @NotBlank(message = "开户行不能为空") + @Length(max = 200, message = "开户行最多200字符") + private String bankName; + + @Schema(description = "启用状态") + @NotNull(message = "启用状态不能为空") + private Boolean disabledFlag; + + @Schema(description = "备注") + @Length(max = 500, message = "备注最多500字符") + private String remark; + + @Schema(description = "企业") + @NotNull(message = "企业不能为空") + private Long enterpriseId; + + @Schema(description = "创建人", hidden = true) + private Long createUserId; + + @Schema(description = "创建人名称", hidden = true) + private String createUserName; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java new file mode 100644 index 0000000..3fcde0f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java @@ -0,0 +1,98 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel; + +import java.time.LocalDateTime; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_oa_invoice") +public class InvoiceEntity { + + /** + * 发票信息ID + */ + @TableId(type = IdType.AUTO) + private Long invoiceId; + + /** + * 开票抬头 + */ + @DataTracerFieldLabel("开票抬头") + private String invoiceHeads; + + /** + * 纳税人识别号 + */ + @DataTracerFieldLabel("纳税人识别号") + private String taxpayerIdentificationNumber; + + /** + * 银行账户 + */ + @DataTracerFieldLabel("银行账户") + private String accountNumber; + + /** + * 开户行 + */ + @DataTracerFieldLabel("开户行") + private String bankName; + + /** + * 备注 + */ + @DataTracerFieldLabel("备注") + private String remark; + + /** + * 企业ID + */ + private Long enterpriseId; + + /** + * 禁用状态 + */ + @DataTracerFieldLabel("禁用状态") + private Boolean disabledFlag; + + /** + * 删除状态 + */ + @DataTracerFieldLabel("删除状态") + private Boolean deletedFlag; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人ID + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java new file mode 100644 index 0000000..497778f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * OA发票信息查询 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class InvoiceQueryForm extends PageParam { + + @Schema(description = "企业ID") + private Long enterpriseId; + + @Schema(description = "关键字") + @Length(max = 200, message = "关键字最多200字符") + private String keywords; + + @Schema(description = "开始时间") + private LocalDate startTime; + + @Schema(description = "结束时间") + private LocalDate endTime; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "删除状态", hidden = true) + private Boolean deletedFlag; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java new file mode 100644 index 0000000..3a84a64 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * OA发票信息编辑 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class InvoiceUpdateForm extends InvoiceAddForm { + + @Schema(description = "发票信息ID") + @NotNull(message = "发票信息ID不能为空") + private Long invoiceId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java new file mode 100644 index 0000000..2e9e645 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class InvoiceVO { + + @Schema(description = "发票信息ID") + private Long invoiceId; + + @Schema(description = "开票抬头") + private String invoiceHeads; + + @Schema(description = "纳税人识别号") + private String taxpayerIdentificationNumber; + + @Schema(description = "银行账户") + private String accountNumber; + + @Schema(description = "开户行") + private String bankName; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "企业") + private Long enterpriseId; + + @Schema(description = "企业名称") + private String enterpriseName; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "创建人ID") + private Long createUserId; + + @Schema(description = "创建人名称") + private String createUserName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/service/InvoiceService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/service/InvoiceService.java new file mode 100644 index 0000000..479bccb --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/service/InvoiceService.java @@ -0,0 +1,144 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.oa.enterprise.service.EnterpriseService; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.admin.module.business.oa.invoice.dao.InvoiceDao; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.*; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class InvoiceService { + + @Resource + private InvoiceDao invoiceDao; + + @Resource + private EnterpriseService enterpriseService; + + @Resource + private DataTracerService dataTracerService; + + /** + * 分页查询发票信息 + */ + public ResponseDTO> queryByPage(InvoiceQueryForm queryForm) { + queryForm.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List invoiceList = invoiceDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, invoiceList); + return ResponseDTO.ok(pageResult); + } + + public ResponseDTO> queryList(Long enterpriseId) { + InvoiceQueryForm queryForm = new InvoiceQueryForm(); + queryForm.setDeletedFlag(Boolean.FALSE); + queryForm.setDisabledFlag(Boolean.FALSE); + queryForm.setEnterpriseId(enterpriseId); + List invoiceList = invoiceDao.queryPage(null, queryForm); + return ResponseDTO.ok(invoiceList); + } + + /** + * 查询发票信息详情 + */ + public ResponseDTO getDetail(Long invoiceId) { + // 校验发票信息是否存在 + InvoiceVO invoiceVO = invoiceDao.getDetail(invoiceId, Boolean.FALSE); + if (Objects.isNull(invoiceVO)) { + return ResponseDTO.userErrorParam("发票信息不存在"); + } + return ResponseDTO.ok(invoiceVO); + } + + /** + * 新建发票信息 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createInvoice(InvoiceAddForm createVO) { + Long enterpriseId = createVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseVO enterpriseVO = enterpriseService.getDetail(enterpriseId); + if (Objects.isNull(enterpriseVO)) { + return ResponseDTO.userErrorParam("企业不存在"); + } + // 验证发票信息账号是否重复 + InvoiceEntity validateInvoice = invoiceDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE); + if (Objects.nonNull(validateInvoice)) { + return ResponseDTO.userErrorParam("发票信息账号重复"); + } + // 数据插入 + InvoiceEntity insertInvoice = SmartBeanUtil.copy(createVO, InvoiceEntity.class); + invoiceDao.insert(insertInvoice); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertInvoice)); + return ResponseDTO.ok(); + } + + /** + * 编辑发票信息 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateInvoice(InvoiceUpdateForm updateVO) { + Long enterpriseId = updateVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseVO enterpriseVO = enterpriseService.getDetail(enterpriseId); + if (Objects.isNull(enterpriseVO)) { + return ResponseDTO.userErrorParam("企业不存在"); + } + Long invoiceId = updateVO.getInvoiceId(); + // 校验发票信息是否存在 + InvoiceEntity invoiceDetail = invoiceDao.selectById(invoiceId); + if (Objects.isNull(invoiceDetail) || invoiceDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("发票信息不存在"); + } + // 验证发票信息账号是否重复 + InvoiceEntity validateInvoice = invoiceDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), invoiceId, Boolean.FALSE); + if (Objects.nonNull(validateInvoice)) { + return ResponseDTO.userErrorParam("发票信息账号重复"); + } + // 数据编辑 + InvoiceEntity updateInvoice = SmartBeanUtil.copy(updateVO, InvoiceEntity.class); + invoiceDao.updateById(updateInvoice); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(invoiceDetail, updateInvoice)); + return ResponseDTO.ok(); + } + + + /** + * 删除发票信息 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteInvoice(Long invoiceId) { + // 校验发票信息是否存在 + InvoiceEntity invoiceDetail = invoiceDao.selectById(invoiceId); + if (Objects.isNull(invoiceDetail) || invoiceDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("发票信息不存在"); + } + invoiceDao.deleteInvoice(invoiceId, Boolean.TRUE); + dataTracerService.addTrace(invoiceDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(invoiceDetail)); + return ResponseDTO.ok(); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java new file mode 100644 index 0000000..eb4784f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.business.oa.notice.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 公告、通知 可见范围类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Getter +@AllArgsConstructor +public enum NoticeVisibleRangeDataTypeEnum implements BaseEnum { + + /** + * 员工 + */ + EMPLOYEE(1, "员工"), + + /** + * 部门 + */ + DEPARTMENT(2, "部门"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java new file mode 100644 index 0000000..d54b60c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java @@ -0,0 +1,140 @@ +package net.lab1024.sa.admin.module.business.oa.notice.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.extra.servlet.ServletUtil; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.*; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*; +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeEmployeeService; +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeService; +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeTypeService; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog; +import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * 公告、通知、新闻等等 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat 卓大1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = AdminSwaggerTagConst.Business.OA_NOTICE) +@RestController +@OperateLog +public class NoticeController { + + @Resource + private NoticeService noticeService; + + @Resource + private NoticeTypeService noticeTypeService; + + @Resource + private NoticeEmployeeService noticeEmployeeService; + + // --------------------- 通知公告类型 ------------------------- + + @Operation(summary = "通知公告类型-获取全部 @author 卓大") + @GetMapping("/oa/noticeType/getAll") + public ResponseDTO> getAll() { + return ResponseDTO.ok(noticeTypeService.getAll()); + } + + @Operation(summary = "通知公告类型-添加 @author 卓大") + @GetMapping("/oa/noticeType/add/{name}") + public ResponseDTO add(@PathVariable String name) { + return noticeTypeService.add(name); + } + + @Operation(summary = "通知公告类型-修改 @author 卓大") + @GetMapping("/oa/noticeType/update/{noticeTypeId}/{name}") + public ResponseDTO update(@PathVariable Long noticeTypeId, @PathVariable String name) { + return noticeTypeService.update(noticeTypeId, name); + } + + @Operation(summary = "通知公告类型-删除 @author 卓大") + @GetMapping("/oa/noticeType/delete/{noticeTypeId}") + public ResponseDTO deleteNoticeType(@PathVariable Long noticeTypeId) { + return noticeTypeService.delete(noticeTypeId); + } + + // --------------------- 【管理】通知公告------------------------- + + + @Operation(summary = "【管理】通知公告-分页查询 @author 卓大") + @PostMapping("/oa/notice/query") + @SaCheckPermission("oa:notice:query") + public ResponseDTO> query(@RequestBody @Valid NoticeQueryForm queryForm) { + return ResponseDTO.ok(noticeService.query(queryForm)); + } + + @Operation(summary = "【管理】通知公告-添加 @author 卓大") + @PostMapping("/oa/notice/add") + @RepeatSubmit + @SaCheckPermission("oa:notice:add") + public ResponseDTO add(@RequestBody @Valid NoticeAddForm addForm) { + addForm.setCreateUserId(SmartRequestUtil.getRequestUserId()); + return noticeService.add(addForm); + } + + @Operation(summary = "【管理】通知公告-更新 @author 卓大") + @PostMapping("/oa/notice/update") + @RepeatSubmit + @SaCheckPermission("oa:notice:update") + public ResponseDTO update(@RequestBody @Valid NoticeUpdateForm updateForm) { + return noticeService.update(updateForm); + } + + @Operation(summary = "【管理】通知公告-更新详情 @author 卓大") + @GetMapping("/oa/notice/getUpdateVO/{noticeId}") + @SaCheckPermission("oa:notice:update") + public ResponseDTO getUpdateFormVO(@PathVariable Long noticeId) { + return ResponseDTO.ok(noticeService.getUpdateFormVO(noticeId)); + } + + @Operation(summary = "【管理】通知公告-删除 @author 卓大") + @GetMapping("/oa/notice/delete/{noticeId}") + @SaCheckPermission("oa:notice:delete") + public ResponseDTO delete(@PathVariable Long noticeId) { + return noticeService.delete(noticeId); + } + + // --------------------- 【员工】查看 通知公告 ------------------------- + + + @Operation(summary = "【员工】通知公告-查看详情 @author 卓大") + @GetMapping("/oa/notice/employee/view/{noticeId}") + public ResponseDTO view(@PathVariable Long noticeId, HttpServletRequest request) { + return noticeEmployeeService.view( + SmartRequestUtil.getRequestUserId(), + noticeId, + ServletUtil.getClientIP(request), + request.getHeader("User-Agent") + ); + } + + @Operation(summary = "【员工】通知公告-查询全部 @author 卓大") + @PostMapping("/oa/notice/employee/query") + public ResponseDTO> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) { + return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm); + } + + @Operation(summary = "【员工】通知公告-查询 查看记录 @author 卓大") + @PostMapping("/oa/notice/employee/queryViewRecord") + public ResponseDTO> queryViewRecord(@RequestBody @Valid NoticeViewRecordQueryForm noticeViewRecordQueryForm) { + return ResponseDTO.ok(noticeEmployeeService.queryViewRecord(noticeViewRecordQueryForm)); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java new file mode 100644 index 0000000..2583c4f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java @@ -0,0 +1,127 @@ +package net.lab1024.sa.admin.module.business.oa.notice.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeEmployeeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeViewRecordQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeEmployeeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeViewRecordVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVisibleRangeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 公告、通知、新闻等等 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface NoticeDao extends BaseMapper { + + // ================================= 数据范围相关 【子表】 ================================= + + /** + * 保存可见范围 + * + */ + void insertVisibleRange(@Param("noticeId") Long noticeId, @Param("visibleRangeFormList") List visibleRangeFormList); + + /** + * 删除可见范围 + * + */ + void deleteVisibleRange(@Param("noticeId") Long noticeId); + + /** + * 相关可见范围 + * + */ + List queryVisibleRange(@Param("noticeId") Long noticeId); + + // ================================= 通知公告【主表】 相关 ================================= + + /** + * 后管分页查询资讯 + * + */ + List query(Page page, @Param("query") NoticeQueryForm queryForm); + + + /** + * 更新删除状态 + * + */ + void updateDeletedFlag(@Param("noticeId") Long noticeId); + + // ================================= 通知公告【员工查看】 相关 ================================= + + /** + * 查询 员工 查看到的通知公告 + * + */ + List queryEmployeeNotice(Page page, + @Param("requestEmployeeId") Long requestEmployeeId, + @Param("query") NoticeEmployeeQueryForm noticeEmployeeQueryForm, + @Param("requestEmployeeDepartmentIdList") List requestEmployeeDepartmentIdList, + @Param("deletedFlag") boolean deletedFlag, + @Param("administratorFlag") boolean administratorFlag, + @Param("departmentDataType") Integer departmentDataType, + @Param("employeeDataType") Integer employeeDataType + + ); + + /** + * 查询 员工 未读的通知公告 + * + */ + List queryEmployeeNotViewNotice(Page page, + @Param("requestEmployeeId") Long requestEmployeeId, + @Param("query") NoticeEmployeeQueryForm noticeEmployeeQueryForm, + @Param("requestEmployeeDepartmentIdList") List requestEmployeeDepartmentIdList, + @Param("deletedFlag") boolean deletedFlag, + @Param("administratorFlag") boolean administratorFlag, + @Param("departmentDataType") Integer departmentDataType, + @Param("employeeDataType") Integer employeeDataType + + ); + + long viewRecordCount(@Param("noticeId")Long noticeId, @Param("employeeId")Long employeeId); + + /** + * 查询通知、公告的 查看记录 + */ + List queryNoticeViewRecordList(Page page,@Param("queryForm") NoticeViewRecordQueryForm noticeViewRecordQueryForm); + + /** + * 保存查看记录 + */ + void insertViewRecord(@Param("noticeId") Long noticeId, @Param("employeeId") Long employeeId, @Param("ip") String ip, @Param("userAgent") String userAgent,@Param("pageViewCount") Integer pageViewCount); + + /** + * 更新查看记录 + */ + void updateViewRecord(@Param("noticeId")Long noticeId, @Param("employeeId")Long requestEmployeeId,@Param("ip") String ip, @Param("userAgent")String userAgent); + + /** + * 更新 浏览量 + * + * @param noticeId 通知 id + * @param pageViewCountIncrement 页面浏览量的增量 + * @param userViewCountIncrement 用户浏览量的增量 + */ + void updateViewCount(@Param("noticeId")Long noticeId,@Param("pageViewCountIncrement") Integer pageViewCountIncrement, @Param("userViewCountIncrement")Integer userViewCountIncrement); + + + NoticeEntity queryById(@Param("noticeId")Long noticeId); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java new file mode 100644 index 0000000..7f7ee5c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.oa.notice.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeTypeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 通知公告类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface NoticeTypeDao extends BaseMapper { + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java new file mode 100644 index 0000000..af7433b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java @@ -0,0 +1,99 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 通知公告 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_notice") +public class NoticeEntity { + + @TableId(type = IdType.AUTO) + private Long noticeId; + + /** + * 类型 + */ + private Long noticeTypeId; + + /** + * 标题 + */ + private String title; + + /** + * 是否全部可见 + */ + private Boolean allVisibleFlag; + + /** + * 是否定时发布 + */ + private Boolean scheduledPublishFlag; + + /** + * 发布时间 + */ + private LocalDateTime publishTime; + + /** + * 内容 纯文本 + */ + private String contentText; + + /** + * 内容 html + */ + private String contentHtml; + + /** + * 附件 + * 多个英文逗号分隔 + */ + private String attachment; + + /** + * 页面浏览量 + */ + private Integer pageViewCount; + + /** + * 用户浏览量 + */ + private Integer userViewCount; + + /** + * 来源 + */ + private String source; + + /** + * 作者 + */ + private String author; + + /** + * 文号 + */ + private String documentNumber; + + private Boolean deletedFlag; + + private Long createUserId; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java new file mode 100644 index 0000000..48c1c8f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 通知公告类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_notice_type") +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class NoticeTypeEntity { + + @TableId(type = IdType.AUTO) + private Long noticeTypeId; + + /** + * 名称 + */ + private String noticeTypeName; + + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java new file mode 100644 index 0000000..cf11779 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 通知公告 添加表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeAddForm { + + @Schema(description = "标题") + @NotBlank(message = "标题不能为空") + @Length(max = 200, message = "标题最多200字符") + private String title; + + @Schema(description = "分类") + @NotNull(message = "分类不能为空") + private Long noticeTypeId; + + @Schema(description = "是否全部可见") + @NotNull(message = "是否全部可见不能为空") + private Boolean allVisibleFlag; + + @Schema(description = "是否定时发布") + @NotNull(message = "是否定时发布不能为空") + private Boolean scheduledPublishFlag; + + @Schema(description = "发布时间") + @NotNull(message = "发布时间不能为空") + private LocalDateTime publishTime; + + @Schema(description = "纯文本内容") + @NotNull(message = "文本内容不能为空") + private String contentText; + + @Schema(description = "html内容") + @NotNull(message = "html内容不能为空") + private String contentHtml; + + @Schema(description = "附件,多个英文逗号分隔|可选") + @Length(max = 1000, message = "最多1000字符") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String attachment; + + @Schema(description = "作者") + @NotBlank(message = "作者不能为空") + private String author; + + @Schema(description = "来源") + @NotBlank(message = "标题不能为空") + private String source; + + @Schema(description = "文号") + private String documentNumber; + + @Schema(hidden = true) + private Long createUserId; + + @Schema(description = "可见范围设置|可选") + @Valid + private List visibleRangeList; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java new file mode 100644 index 0000000..3f3d90b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 通知公告 员工查询表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeEmployeeQueryForm extends PageParam { + + @Schema(description = "标题、作者、来源、文号") + private String keywords; + + @Schema(description = "分类") + private Long noticeTypeId; + + @Schema(description = "发布-开始时间") + private LocalDate publishTimeBegin; + + @Schema(description = "未读标识") + private Boolean notViewFlag; + + @Schema(description = "发布-截止时间") + private LocalDate publishTimeEnd; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java new file mode 100644 index 0000000..1e9544b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 通知公告 管理查询表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeQueryForm extends PageParam { + + @Schema(description = "分类") + private Long noticeTypeId; + + @Schema(description = "标题、作者、来源") + private String keywords; + + @Schema(description = "文号") + private String documentNumber; + + @Schema(description = "创建人") + private String createUserName; + + @Schema(description = "删除标识") + private Boolean deletedFlag; + + @Schema(description = "创建-开始时间") + private LocalDate createTimeBegin; + + @Schema(description = "创建-截止时间") + private LocalDate createTimeEnd; + + @Schema(description = "发布-开始时间") + private LocalDate publishTimeBegin; + + @Schema(description = "发布-截止时间") + private LocalDate publishTimeEnd; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java new file mode 100644 index 0000000..93f812b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 通知公告 更新表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeUpdateForm extends NoticeAddForm { + + @Schema(description = "id") + @NotNull(message = "通知id不能为空") + private Long noticeId; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java new file mode 100644 index 0000000..2536356 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 通知公告 阅读记录查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeViewRecordQueryForm extends PageParam { + + @Schema(description = "通知公告id") + @NotNull(message = "通知公告id不能为空") + private Long noticeId; + + @Schema(description = "部门id") + private Long departmentId; + + @Schema(description = "关键字") + private String keywords; + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java new file mode 100644 index 0000000..7cf9a50 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; + +import javax.validation.constraints.NotNull; + +/** + * 通知公告 可见范围数据 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class NoticeVisibleRangeForm { + + @SchemaEnum(NoticeVisibleRangeDataTypeEnum.class) + @CheckEnum(value = NoticeVisibleRangeDataTypeEnum.class, required = true, message = "数据类型错误") + private Integer dataType; + + @Schema(description = "员工/部门id") + @NotNull(message = "员工/部门id不能为空") + private Long dataId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java new file mode 100644 index 0000000..cecbbcf --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java @@ -0,0 +1,84 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * 通知公告 详情 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeDetailVO { + + @Schema(description = "id") + private Long noticeId; + + @Schema(description = "标题") + private String title; + + @Schema(description = "分类") + private Long noticeTypeId; + + @Schema(description = "分类名称") + private Long noticeTypeName; + + @Schema(description = "是否全部可见") + @NotNull(message = "是否全部可见不能为空") + private Boolean allVisibleFlag; + + @Schema(description = "是否定时发布") + @NotNull(message = "是否定时发布不能为空") + private Boolean scheduledPublishFlag; + + @Schema(description = "纯文本内容") + private String contentText; + + @Schema(description = "html内容") + private String contentHtml; + + @Schema(description = "附件") + @JsonSerialize(using = FileKeyVoSerializer.class) + private String attachment; + + @Schema(description = "发布时间") + @NotNull(message = "发布时间不能为空") + private LocalDateTime publishTime; + + @Schema(description = "作者") + @NotBlank(message = "作者不能为空") + private String author; + + @Schema(description = "来源") + @NotBlank(message = "标题不能为空") + private String source; + + @Schema(description = "文号") + private String documentNumber; + + @Schema(description = "页面浏览量") + private Integer pageViewCount; + + @Schema(description = "用户浏览量") + private Integer userViewCount; + + @Schema(description = "创建人名称") + private Long createUserName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java new file mode 100644 index 0000000..759ba6c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDate; + +/** + * 通知公告 员工查看 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeEmployeeVO extends NoticeVO { + + @Schema(description = "是否查看") + private Boolean viewFlag; + + @Schema(description = "发布日期") + private LocalDate publishDate; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java new file mode 100644 index 0000000..2660959 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 通知公告 类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeTypeVO { + + @Schema(description = "通知类型id") + private Long noticeTypeId; + + @Schema(description = "通知类型-名称") + private String noticeTypeName; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java new file mode 100644 index 0000000..1302559 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; + +import java.util.List; + +/** + * 用于更新 【通知、公告】 的 VO 对象 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeUpdateFormVO extends NoticeVO { + + @Schema(description = "纯文本内容") + private String contentText; + + @Schema(description = "html内容") + private String contentHtml; + + @Schema(description = "附件") + @JsonSerialize(using = FileKeyVoSerializer.class) + private String attachment; + + @Schema(description = "可见范围") + private List visibleRangeList; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java new file mode 100644 index 0000000..dbfcfac --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; + + +/** + * 新闻、公告 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeVO { + + @Schema(description = "id") + private Long noticeId; + + @Schema(description = "标题") + private String title; + + @Schema(description = "分类") + private Long noticeTypeId; + + @Schema(description = "分类名称") + private String noticeTypeName; + + @Schema(description = "是否全部可见") + private Boolean allVisibleFlag; + + @Schema(description = "是否定时发布") + private Boolean scheduledPublishFlag; + + @Schema(description = "发布状态") + private Boolean publishFlag; + + @Schema(description = "发布时间") + private LocalDateTime publishTime; + + @Schema(description = "作者") + private String author; + + @Schema(description = "来源") + private String source; + + @Schema(description = "文号") + private String documentNumber; + + @Schema(description = "页面浏览量") + private Integer pageViewCount; + + @Schema(description = "用户浏览量") + private Integer userViewCount; + + @Schema(description = "删除标识") + private Boolean deletedFlag; + + @Schema(description = "创建人名称") + private String createUserName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java new file mode 100644 index 0000000..23b1adc --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 浏览记录 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeViewRecordVO { + + @Schema(description = "员工ID") + private Long employeeId; + + @Schema(description = "员工姓名") + private String employeeName; + + @Schema(description = "员工部门名称") + private String departmentName; + + @Schema(description = "查看次数") + private Integer pageViewCount; + + @Schema(description = "首次ip") + private String firstIp; + + @Schema(description = "首次用户设备等标识") + private String firstUserAgent; + + @Schema(description = "首次查看时间") + private LocalDateTime createTime; + + @Schema(description = "最后一次 ip") + private String lastIp; + + @Schema(description = "最后一次 用户设备等标识") + private String lastUserAgent; + + @Schema(description = "最后一次查看时间") + private LocalDateTime updateTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java new file mode 100644 index 0000000..0206cad --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +/** + * 新闻、公告 可见范围数据 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class NoticeVisibleRangeVO { + + @SchemaEnum(NoticeVisibleRangeDataTypeEnum.class) + private Integer dataType; + + @Schema(description = "员工/部门id") + private Long dataId; + + @Schema(description = "员工/部门 名称") + private String dataName; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java new file mode 100644 index 0000000..2a480cb --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.module.business.oa.notice.manager; + +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 通知、公告 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class NoticeManager { + + @Resource + private NoticeDao noticeDao; + + @Resource + private DataTracerService dataTracerService; + + /** + * 保存 + */ + @Transactional(rollbackFor = Throwable.class) + public void save(NoticeEntity noticeEntity, List visibleRangeFormList) { + noticeDao.insert(noticeEntity); + Long noticeId = noticeEntity.getNoticeId(); + // 保存可见范围 + if (CollectionUtils.isNotEmpty(visibleRangeFormList)) { + noticeDao.insertVisibleRange(noticeId, visibleRangeFormList); + } + dataTracerService.insert(noticeId, DataTracerTypeEnum.OA_NOTICE); + } + + /** + * 更新 + * + */ + @Transactional(rollbackFor = Throwable.class) + public void update(NoticeEntity old, NoticeEntity noticeEntity, List visibleRangeList) { + noticeDao.updateById(noticeEntity); + Long noticeId = noticeEntity.getNoticeId(); + // 保存可见范围 + if (CollectionUtils.isNotEmpty(visibleRangeList)) { + noticeDao.deleteVisibleRange(noticeId); + noticeDao.insertVisibleRange(noticeId, visibleRangeList); + } + dataTracerService.update(noticeId, DataTracerTypeEnum.OA_NOTICE, old, noticeEntity); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java new file mode 100644 index 0000000..8208a74 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java @@ -0,0 +1,155 @@ +package net.lab1024.sa.admin.module.business.oa.notice.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeEmployeeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeViewRecordQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + + +/** + * 员工查看 通知。公告 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class NoticeEmployeeService { + + @Resource + private NoticeDao noticeDao; + + @Resource + private NoticeService noticeService; + + @Resource + private DepartmentService departmentService; + + @Resource + private EmployeeService employeeService; + + /** + * 查询我的 通知、公告清单 + */ + public ResponseDTO> queryList(Long requestEmployeeId, NoticeEmployeeQueryForm noticeEmployeeQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(noticeEmployeeQueryForm); + + List employeeDepartmentIdList = Lists.newArrayList(); + EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId); + // 如果不是管理员 则获取请求人的 部门及其子部门 + if (!employeeEntity.getAdministratorFlag() && employeeEntity.getDepartmentId() != null) { + employeeDepartmentIdList = departmentService.selfAndChildrenIdList(employeeEntity.getDepartmentId()); + } + + List noticeList = null; + //只查询未读的 + if (noticeEmployeeQueryForm.getNotViewFlag() != null && noticeEmployeeQueryForm.getNotViewFlag()) { + noticeList = noticeDao.queryEmployeeNotViewNotice(page, + requestEmployeeId, + noticeEmployeeQueryForm, + employeeDepartmentIdList, + false, + employeeEntity.getAdministratorFlag(), + NoticeVisibleRangeDataTypeEnum.DEPARTMENT.getValue(), + NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue()); + } else { + // 查询全部 + noticeList = noticeDao.queryEmployeeNotice(page, + requestEmployeeId, + noticeEmployeeQueryForm, + employeeDepartmentIdList, + false, + employeeEntity.getAdministratorFlag(), + NoticeVisibleRangeDataTypeEnum.DEPARTMENT.getValue(), + NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue()); + } + // 设置发布日期 + noticeList.forEach(notice -> notice.setPublishDate(notice.getPublishTime().toLocalDate())); + + return ResponseDTO.ok(SmartPageUtil.convert2PageResult(page, noticeList)); + } + + + /** + * 查询我的 待查看的 通知、公告清单 + */ + public ResponseDTO view(Long requestEmployeeId, Long noticeId, String ip, String userAgent) { + NoticeUpdateFormVO updateFormVO = noticeService.getUpdateFormVO(noticeId); + if (updateFormVO == null || Boolean.TRUE.equals(updateFormVO.getDeletedFlag())) { + return ResponseDTO.userErrorParam("通知公告不存在"); + } + + EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId); + if (!updateFormVO.getAllVisibleFlag() && !checkVisibleRange(updateFormVO.getVisibleRangeList(), requestEmployeeId, employeeEntity.getDepartmentId())) { + return ResponseDTO.userErrorParam("对不起,您没有权限查看内容"); + } + + NoticeDetailVO noticeDetailVO = SmartBeanUtil.copy(updateFormVO, NoticeDetailVO.class); + long viewCount = noticeDao.viewRecordCount(noticeId, requestEmployeeId); + if (viewCount == 0) { + noticeDao.insertViewRecord(noticeId, requestEmployeeId, ip, userAgent, 1); + // 该员工对于这个通知是第一次查看 页面浏览量+1 用户浏览量+1 + noticeDao.updateViewCount(noticeId, 1, 1); + noticeDetailVO.setPageViewCount(noticeDetailVO.getPageViewCount() + 1); + noticeDetailVO.setUserViewCount(noticeDetailVO.getUserViewCount() + 1); + } else { + noticeDao.updateViewRecord(noticeId, requestEmployeeId, ip, userAgent); + // 该员工对于这个通知不是第一次查看 页面浏览量+1 用户浏览量+0 + noticeDao.updateViewCount(noticeId, 1, 0); + noticeDetailVO.setPageViewCount(noticeDetailVO.getPageViewCount() + 1); + } + + return ResponseDTO.ok(noticeDetailVO); + } + + /** + * 校验是否有查看权限的范围 + * + */ + public boolean checkVisibleRange(List visibleRangeList, Long employeeId, Long departmentId) { + // 员工范围 + boolean anyMatch = visibleRangeList.stream().anyMatch(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.equalsValue(e.getDataType()) && Objects.equals(e.getDataId(), employeeId)); + if (anyMatch) { + return true; + } + + //部门范围 + List visibleDepartmentIdList = visibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.DEPARTMENT.equalsValue(e.getDataType())) + .map(NoticeVisibleRangeVO::getDataId).collect(Collectors.toList()); + + for (Long visibleDepartmentId : visibleDepartmentIdList) { + List departmentIdList = departmentService.selfAndChildrenIdList(visibleDepartmentId); + if (departmentIdList.contains(departmentId)) { + return true; + } + } + return false; + } + + /** + * 分页查询 查看记录 + */ + public PageResult queryViewRecord(NoticeViewRecordQueryForm noticeViewRecordQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(noticeViewRecordQueryForm); + List noticeViewRecordList = noticeDao.queryNoticeViewRecordList(page, noticeViewRecordQueryForm); + return SmartPageUtil.convert2PageResult(page, noticeViewRecordList); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java new file mode 100644 index 0000000..bad6060 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java @@ -0,0 +1,244 @@ +package net.lab1024.sa.admin.module.business.oa.notice.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Maps; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeAddForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeUpdateForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeTypeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeUpdateFormVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVisibleRangeVO; +import net.lab1024.sa.admin.module.business.oa.notice.manager.NoticeManager; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 通知。公告 后台管理业务 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class NoticeService { + + @Resource + private NoticeDao noticeDao; + + @Resource + private NoticeManager noticeManager; + + @Resource + private EmployeeDao employeeDao; + + @Resource + private DepartmentDao departmentDao; + + @Resource + private DepartmentService departmentService; + + @Resource + private NoticeTypeService noticeTypeService; + + @Resource + private DataTracerService dataTracerService; + + /** + * 查询 通知、公告 + * + */ + public PageResult query(NoticeQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = noticeDao.query(page, queryForm); + LocalDateTime now = LocalDateTime.now(); + list.forEach(e -> e.setPublishFlag(e.getPublishTime().isBefore(now))); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + */ + public ResponseDTO add(NoticeAddForm addForm) { + // 校验并获取可见范围 + ResponseDTO validate = this.checkAndBuildVisibleRange(addForm); + if (!validate.getOk()) { + return ResponseDTO.error(validate); + } + + // build 资讯 + NoticeEntity noticeEntity = SmartBeanUtil.copy(addForm, NoticeEntity.class); + // 发布时间:不是定时发布时 默认为 当前 + if (!addForm.getScheduledPublishFlag()) { + noticeEntity.setPublishTime(LocalDateTime.now()); + } + // 保存数据 + noticeManager.save(noticeEntity, addForm.getVisibleRangeList()); + return ResponseDTO.ok(); + } + + /** + * 校验并返回可见范围 + * + */ + private ResponseDTO checkAndBuildVisibleRange(NoticeAddForm form) { + // 校验资讯分类 + NoticeTypeVO noticeType = noticeTypeService.getByNoticeTypeId(form.getNoticeTypeId()); + if (noticeType == null) { + return ResponseDTO.userErrorParam("分类不存在"); + } + + if (form.getAllVisibleFlag()) { + return ResponseDTO.ok(); + } + + /* + * 校验可见范围 + * 非全部可见时 校验选择的员工|部门 + */ + List visibleRangeUpdateList = form.getVisibleRangeList(); + if (CollectionUtils.isEmpty(visibleRangeUpdateList)) { + return ResponseDTO.userErrorParam("未设置可见范围"); + } + + // 校验可见范围-> 员工 + List employeeIdList = visibleRangeUpdateList.stream() + .filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.equalsValue(e.getDataType())) + .map(NoticeVisibleRangeForm::getDataId) + .distinct().collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(employeeIdList)) { + employeeIdList = employeeIdList.stream().distinct().collect(Collectors.toList()); + List dbEmployeeIdList = employeeDao.selectBatchIds(employeeIdList).stream().map(EmployeeEntity::getEmployeeId).collect(Collectors.toList()); + Collection subtract = CollectionUtils.subtract(employeeIdList, dbEmployeeIdList); + if (!subtract.isEmpty()) { + return ResponseDTO.userErrorParam("员工id不存在:" + subtract); + } + } + + // 校验可见范围-> 部门 + List deptIdList = visibleRangeUpdateList.stream() + .filter(e -> NoticeVisibleRangeDataTypeEnum.DEPARTMENT.equalsValue(e.getDataType())) + .map(NoticeVisibleRangeForm::getDataId) + .distinct().collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(deptIdList)) { + deptIdList = deptIdList.stream().distinct().collect(Collectors.toList()); + List dbDeptIdList = departmentDao.selectBatchIds(deptIdList).stream().map(DepartmentEntity::getDepartmentId).collect(Collectors.toList()); + Collection subtract = CollectionUtils.subtract(deptIdList, dbDeptIdList); + if (!subtract.isEmpty()) { + return ResponseDTO.userErrorParam("部门id不存在:" + subtract); + } + } + return ResponseDTO.ok(); + } + + + /** + * 更新 + * + */ + public ResponseDTO update(NoticeUpdateForm updateForm) { + + NoticeEntity oldNoticeEntity = noticeDao.selectById(updateForm.getNoticeId()); + if (oldNoticeEntity == null) { + return ResponseDTO.userErrorParam("通知不存在"); + } + + // 校验并获取可见范围 + ResponseDTO res = this.checkAndBuildVisibleRange(updateForm); + if (!res.getOk()) { + return ResponseDTO.error(res); + } + + // 更新 + NoticeEntity noticeEntity = SmartBeanUtil.copy(updateForm, NoticeEntity.class); + noticeManager.update(oldNoticeEntity, noticeEntity, updateForm.getVisibleRangeList()); + return ResponseDTO.ok(); + } + + + /** + * 删除 + * + */ + public ResponseDTO delete(Long noticeId) { + NoticeEntity noticeEntity = noticeDao.selectById(noticeId); + if (null == noticeEntity || noticeEntity.getDeletedFlag()) { + return ResponseDTO.userErrorParam("通知公告不存在"); + } + // 更新删除状态 + noticeDao.updateDeletedFlag(noticeId); + dataTracerService.delete(noticeId, DataTracerTypeEnum.OA_NOTICE); + return ResponseDTO.ok(); + } + + /** + * 获取更新表单用的详情 + */ + public NoticeUpdateFormVO getUpdateFormVO(Long noticeId) { + NoticeEntity noticeEntity = noticeDao.selectById(noticeId); + if (null == noticeEntity) { + return null; + } + + NoticeUpdateFormVO updateFormVO = SmartBeanUtil.copy(noticeEntity, NoticeUpdateFormVO.class); + NoticeTypeVO noticeType = noticeTypeService.getByNoticeTypeId(noticeEntity.getNoticeTypeId()); + updateFormVO.setNoticeTypeName(noticeType.getNoticeTypeName()); + updateFormVO.setPublishFlag(updateFormVO.getPublishTime() != null && updateFormVO.getPublishTime().isBefore(LocalDateTime.now())); + + if (!updateFormVO.getAllVisibleFlag()) { + List noticeVisibleRangeList = noticeDao.queryVisibleRange(noticeId); + List employeeIdList = noticeVisibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue().equals(e.getDataType())) + .map(NoticeVisibleRangeVO::getDataId) + .collect(Collectors.toList()); + + Map employeeMap = null; + if (CollectionUtils.isNotEmpty(employeeIdList)) { + employeeMap = employeeDao.selectBatchIds(employeeIdList).stream().collect(Collectors.toMap(EmployeeEntity::getEmployeeId, Function.identity())); + } else { + employeeMap = Maps.newHashMap(); + } + for (NoticeVisibleRangeVO noticeVisibleRange : noticeVisibleRangeList) { + if (noticeVisibleRange.getDataType().equals(NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue())) { + EmployeeEntity employeeEntity = employeeMap.get(noticeVisibleRange.getDataId()); + noticeVisibleRange.setDataName(employeeEntity == null ? StringConst.EMPTY : employeeEntity.getActualName()); + } else { + DepartmentVO departmentVO = departmentService.getDepartmentById(noticeVisibleRange.getDataId()); + noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getDepartmentName()); + } + } + updateFormVO.setVisibleRangeList(noticeVisibleRangeList); + } + return updateFormVO; + } + + public NoticeEntity queryById(Long noticeId) { + return noticeDao.queryById(noticeId); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java new file mode 100644 index 0000000..4485370 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java @@ -0,0 +1,87 @@ +package net.lab1024.sa.admin.module.business.oa.notice.service; + +import cn.hutool.core.util.StrUtil; +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeTypeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeTypeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeTypeVO; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 通知。公告 类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class NoticeTypeService { + + @Resource + private NoticeTypeDao noticeTypeDao; + + /** + * 查询全部 + * @return + */ + public List getAll() { + return SmartBeanUtil.copyList(noticeTypeDao.selectList(null), NoticeTypeVO.class); + } + + public NoticeTypeVO getByNoticeTypeId(Long noticceTypeId) { + return SmartBeanUtil.copy(noticeTypeDao.selectById(noticceTypeId), NoticeTypeVO.class); + } + + public synchronized ResponseDTO add(String name) { + if (StrUtil.isBlank(name)) { + return ResponseDTO.userErrorParam("类型名称不能为空"); + } + + List noticeTypeEntityList = noticeTypeDao.selectList(null); + if (!CollectionUtils.isEmpty(noticeTypeEntityList)) { + boolean exist = noticeTypeEntityList.stream().map(NoticeTypeEntity::getNoticeTypeName).collect(Collectors.toSet()).contains(name); + if (exist) { + return ResponseDTO.userErrorParam("类型名称已经存在"); + } + } + noticeTypeDao.insert(NoticeTypeEntity.builder().noticeTypeName(name).build()); + return ResponseDTO.ok(); + } + + public synchronized ResponseDTO update(Long noticeTypeId, String name) { + if (StrUtil.isBlank(name)) { + return ResponseDTO.userErrorParam("类型名称不能为空"); + } + + NoticeTypeEntity noticeTypeEntity = noticeTypeDao.selectById(noticeTypeId); + if (noticeTypeEntity == null) { + return ResponseDTO.userErrorParam("类型名称不存在"); + } + + List noticeTypeEntityList = noticeTypeDao.selectList(null); + if (!CollectionUtils.isEmpty(noticeTypeEntityList)) { + Optional optionalNoticeTypeEntity = noticeTypeEntityList.stream().filter(e -> e.getNoticeTypeName().equals(name)).findFirst(); + if (optionalNoticeTypeEntity.isPresent() && !optionalNoticeTypeEntity.get().getNoticeTypeId().equals(noticeTypeId)) { + return ResponseDTO.userErrorParam("类型名称已经存在"); + } + } + noticeTypeEntity.setNoticeTypeName(name); + noticeTypeDao.updateById(noticeTypeEntity); + return ResponseDTO.ok(); + } + + public synchronized ResponseDTO delete(Long noticeTypeId) { + noticeTypeDao.deleteById(noticeTypeId); + return ResponseDTO.ok(); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/controller/LetterController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/controller/LetterController.java new file mode 100644 index 0000000..1fecc8f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/controller/LetterController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.letter.controller; + +import net.lab1024.sa.admin.module.letter.domain.form.LetterQueryForm; +import net.lab1024.sa.admin.module.letter.domain.vo.LetterVO; +import net.lab1024.sa.admin.module.letter.service.LetterService; +import cn.dev33.satoken.annotation.SaCheckPermission; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 承诺书签订表 Controller + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ + +@RestController +@Tag(name = "承诺书签订表") +public class LetterController { + + @Resource + private LetterService letterService; + + @Operation(summary = "分页查询 @author wzh") + @PostMapping("/letter/queryPage") + @SaCheckPermission("letter:query") + public ResponseDTO> queryPage(@RequestBody @Valid LetterQueryForm queryForm) { + return ResponseDTO.ok(letterService.queryPage(queryForm)); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/dao/LetterDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/dao/LetterDao.java new file mode 100644 index 0000000..f440108 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/dao/LetterDao.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.module.letter.dao; + +import java.util.List; +import net.lab1024.sa.admin.module.letter.domain.entity.LetterEntity; +import net.lab1024.sa.admin.module.letter.domain.form.LetterQueryForm; +import net.lab1024.sa.admin.module.letter.domain.vo.LetterVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 承诺书签订表 Dao + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ + +@Mapper +public interface LetterDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") LetterQueryForm queryForm); + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/entity/LetterEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/entity/LetterEntity.java new file mode 100644 index 0000000..a7c6ab4 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/entity/LetterEntity.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.admin.module.letter.domain.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 承诺书签订表 实体类 + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ + +@Data +@TableName("t_letter") +public class LetterEntity { + + /** + * 承诺书id + */ + @TableId(type = IdType.AUTO) + private Integer letterId; + + /** + * 排序 + */ + private Integer sort; + + /** + * 是否禁用 + */ + private Integer disabledFlag; + + /** + * 是否删除 + */ + private Integer deletedFlag; + + /** + * 用户id + */ + private Integer userId; + + /** + * + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; + + /** + * + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/form/LetterQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/form/LetterQueryForm.java new file mode 100644 index 0000000..9d6df90 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/form/LetterQueryForm.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.letter.domain.form; + +import net.lab1024.sa.base.common.domain.PageParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 承诺书签订表 分页查询表单 + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ + +@Data +@EqualsAndHashCode(callSuper = false) +public class LetterQueryForm extends PageParam { + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/vo/LetterVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/vo/LetterVO.java new file mode 100644 index 0000000..880a47d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/domain/vo/LetterVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.letter.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 承诺书签订表 列表VO + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ + +@Data +public class LetterVO { + + + @Schema(description = "承诺书id") + private Long letterId; + @Schema(description = "承诺书名称") + private String letterName; + @Schema(description = "排序") + private Integer sort; + + @Schema(description = "是否禁用") + private Integer disabledFlag; + + @Schema(description = "是否删除") + private Integer deletedFlag; + + @Schema(description = "用户id") + private Long userId; + @Schema(description = "用户名称") + private String userName; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/manager/LetterManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/manager/LetterManager.java new file mode 100644 index 0000000..7c06119 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/manager/LetterManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.letter.manager; + +import net.lab1024.sa.admin.module.letter.domain.entity.LetterEntity; +import net.lab1024.sa.admin.module.letter.dao.LetterDao; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 承诺书签订表 Manager + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ +@Service +public class LetterManager extends ServiceImpl { + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/service/LetterService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/service/LetterService.java new file mode 100644 index 0000000..fae41db --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/service/LetterService.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.admin.module.letter.service; + +import java.util.List; + +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeService; +import net.lab1024.sa.admin.module.letter.dao.LetterDao; +import net.lab1024.sa.admin.module.letter.domain.form.LetterQueryForm; +import net.lab1024.sa.admin.module.letter.domain.vo.LetterVO; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.domain.PageResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 承诺书签订表 Service + * + * @Author wzh + * @Date 2025-12-22 17:43:06 + * @Copyright 1 + */ + +@Service +public class LetterService { + + @Resource + private LetterDao letterDao; + @Resource + private EmployeeService employeeService; + @Resource + private NoticeService noticeService; + + /** + * 分页查询 + */ + public PageResult queryPage(LetterQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = letterDao.queryPage(page, queryForm); + //查询用户名称 + list.forEach(item -> { + item.setUserName(employeeService.queryById(item.getUserId()).getActualName()); + item.setLetterName(noticeService.queryById(item.getLetterId()).getTitle()); + }); + return SmartPageUtil.convert2PageResult(page, list); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/sql/LetterMenu.sql b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/sql/LetterMenu.sql new file mode 100644 index 0000000..80ec17a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/letter/sql/LetterMenu.sql @@ -0,0 +1,22 @@ +# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下, +# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。 +# 如果你一切都是按照默认,那么下面的 SQL 基本不用改 + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id ) +VALUES ( '承诺书签订表', 2, 0, '/letter/list', '/business/letter/letter-list.vue', false, false, true, false, 1, 1 ); + +# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID +SET @parent_id = NULL; +SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '承诺书签订表'; + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '查询', 3, @parent_id, false, false, true, false, 1, 'letter:query', 'letter:query', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '添加', 3, @parent_id, false, false, true, false, 1, 'letter:add', 'letter:add', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '更新', 3, @parent_id, false, false, true, false, 1, 'letter:update', 'letter:update', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '删除', 3, @parent_id, false, false, true, false, 1, 'letter:delete', 'letter:delete', @parent_id, 1 ); diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java new file mode 100644 index 0000000..26110aa --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java @@ -0,0 +1,97 @@ +package net.lab1024.sa.admin.module.service.controller; + +import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsAddForm; +import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsQueryForm; +import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsUpdateForm; +import net.lab1024.sa.admin.module.service.domain.vo.ServiceApplicationsVO; +import net.lab1024.sa.admin.module.service.service.ServiceApplicationsService; +import net.lab1024.sa.base.common.domain.ValidateList; +import org.springframework.web.bind.annotation.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +/** + * 服务申报表 Controller + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@RestController +@Tag(name = "服务申报表") +public class ServiceApplicationsController { + + @Resource + private ServiceApplicationsService serviceApplicationsService; + + @Operation(summary = "分页查询 @author wzh") + @PostMapping("/serviceApplications/queryPage") + @SaCheckPermission("serviceApplications:query") + public ResponseDTO> queryPage(@RequestBody @Valid ServiceApplicationsQueryForm queryForm) { + return ResponseDTO.ok(serviceApplicationsService.queryPage(queryForm)); + } + + @Operation(summary = "添加 @author wzh") + @PostMapping("/serviceApplications/add") + @SaCheckPermission("serviceApplications:add") + public ResponseDTO add(@RequestBody @Valid ServiceApplicationsAddForm addForm) { + return serviceApplicationsService.add(addForm); + } + + @Operation(summary = "更新 @author wzh") + @PostMapping("/serviceApplications/update") + @SaCheckPermission("serviceApplications:update") + public ResponseDTO update(@RequestBody @Valid ServiceApplicationsUpdateForm updateForm) { + return serviceApplicationsService.update(updateForm); + } + + @Operation(summary = "批量提交 @author wzh") + @PostMapping("/serviceApplications/batchSubmit") + @SaCheckPermission("serviceApplications:batchSubmit") + public ResponseDTO batchSubmit(@RequestBody ValidateList idList) { + return serviceApplicationsService.batchSubmit(idList); + } + + @Operation(summary = "提交 @author wzh") + @GetMapping("/serviceApplications/submit/{applicationId}") + @SaCheckPermission("serviceApplications:submit") + public ResponseDTO submit(@PathVariable Integer applicationId) { + return serviceApplicationsService.submit(applicationId); + } + + @Operation(summary = "批量删除 @author wzh") + @PostMapping("/serviceApplications/batchDelete") + @SaCheckPermission("serviceApplications:delete") + public ResponseDTO batchDelete(@RequestBody ValidateList idList) { + return serviceApplicationsService.batchDelete(idList); + } + + @Operation(summary = "单个删除 @author wzh") + @GetMapping("/serviceApplications/delete/{applicationId}") + @SaCheckPermission("serviceApplications:delete") + public ResponseDTO batchDelete(@PathVariable Integer applicationId) { + return serviceApplicationsService.delete(applicationId); + } + + @Operation(summary = "导入 @author wzh") + @PostMapping("/serviceApplications/importService") + @SaCheckPermission("serviceApplications:importService") + public ResponseDTO importService(@RequestParam MultipartFile file) { + return serviceApplicationsService.importService(file); + } + + @Operation(summary = "模板下载 @author wzh") + @GetMapping("/serviceApplications/downloadTemplate") + @SaCheckPermission("serviceApplications:downloadTemplate") + public void downloadTemplate(HttpServletResponse response) { + serviceApplicationsService.downloadTemplate(response); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java new file mode 100644 index 0000000..cfb122e --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.service.dao; + +import java.util.List; +import net.lab1024.sa.admin.module.service.domain.entity.ServiceApplicationsEntity; +import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsQueryForm; +import net.lab1024.sa.admin.module.service.domain.vo.ServiceApplicationsVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.ValidateList; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 服务申报表 Dao + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@Mapper +public interface ServiceApplicationsDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") ServiceApplicationsQueryForm queryForm); + + /** + * 更新删除状态 + */ + long updateDeleted(@Param("applicationId")Integer applicationId,@Param("deletedFlag")boolean deletedFlag); + + /** + * 批量更新删除状态 + */ + void batchUpdateDeleted(@Param("idList")List idList,@Param("deletedFlag")boolean deletedFlag); + + void batchSubmit(@Param("idList")List idList, @Param("deletedFlag")Integer b); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.java new file mode 100644 index 0000000..ca91b3b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.java @@ -0,0 +1,175 @@ +package net.lab1024.sa.admin.module.service.domain.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 服务申报表 实体类 + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@Data +@TableName("t_service_applications") +public class ServiceApplicationsEntity { + + /** + * 申报ID + */ + @TableId(type = IdType.AUTO) + private Integer applicationId; + + /** + * 申报律师ID + */ + private Integer userId; + + /** + * 律所ID + */ + private Integer firmId; + + /** + * 服务开始时间 + */ + private LocalDateTime serviceStart; + + /** + * 服务结束时间 + */ + private LocalDateTime serviceEnd; + + /** + * 服务时长(小时) + */ + private BigDecimal serviceDuration; + + /** + * 受益人数 + */ + private Integer beneficiaryCount; + + /** + * 组织单位名称 + */ + private String organizerName; + + /** + * 负责人姓名 + */ + private String organizerContact; + + /** + * 联系方式 + */ + private String organizerPhone; + + /** + * 服务内容描述 + */ + private String serviceContent; + + /** + * 工作量换算得分 + */ + private BigDecimal workloadScore; + + /** + * 律所审核状态:0-待审核,1-通过,2-退回 + */ + private Integer firmAuditStatus; + + /** + * 律所审核意见 + */ + private String firmAuditOpinion; + + /** + * 律所审核人 + */ + private Integer firmAuditUser; + + /** + * 律所审核时间 + */ + private LocalDateTime firmAuditTime; + + /** + * 协会审核状态:0-待审核,1-通过,2-退回 + */ + private Integer associationAuditStatus; + + /** + * 协会审核意见 + */ + private String associationAuditOpinion; + + /** + * 协会审核人 + */ + private Integer associationAuditUser; + + /** + * 协会审核时间 + */ + private LocalDateTime associationAuditTime; + + /** + * 备案编号 + */ + private String recordNo; + + /** + * 备案状态:0-未备案,1-已备案 + */ + private Integer recordStatus; + + /** + * 备案时间 + */ + private LocalDateTime recordTime; + + /** + * + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; + + /** + * + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 删除字段 + */ + private Integer deletedFlag; + + /** + * 职业证号 + */ + private String certificateNumber; + + /** + * 活动类别 + */ + private String activityCategoryId; + /** + * 活动名称 + */ + private String activityNameId; + + /** + * 附件id + */ + private String attachmentIds; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsAddForm.java new file mode 100644 index 0000000..f06c942 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsAddForm.java @@ -0,0 +1,76 @@ +package net.lab1024.sa.admin.module.service.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; + +/** + * 服务申报表 新建表单 + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@Data +public class ServiceApplicationsAddForm { + + @Schema(description = "申报律师", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "申报律师 不能为空") + private Integer userId; + + @Schema(description = "律所", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "律所 不能为空") + private Integer firmId; + + @Schema(description = "服务开始时间", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "服务开始时间 不能为空") + private LocalDateTime serviceStart; + + @Schema(description = "服务结束时间", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "服务结束时间 不能为空") + private LocalDateTime serviceEnd; + + @Schema(description = "服务时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "服务时长(小时) 不能为空") + private BigDecimal serviceDuration; + + @Schema(description = "受益人数", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "受益人数 不能为空") + private Integer beneficiaryCount; + + @Schema(description = "组织单位名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "组织单位名称 不能为空") + private String organizerName; + + @Schema(description = "负责人姓名", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "负责人姓名 不能为空") + private String organizerContact; + + @Schema(description = "联系方式", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "联系方式 不能为空") + private String organizerPhone; + + @Schema(description = "服务内容描述", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "服务内容描述 不能为空") + private String serviceContent; + + @Schema(description = "职业证号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "职业证号 不能为空") + private String certificateNumber; + + @Schema(description = "活动类别", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "活动类别 不能为空") + private String activityCategoryId; + + @Schema(description = "活动名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "活动名称 不能为空") + private String activityNameId; + + @Schema(description = "附件id集合", requiredMode = Schema.RequiredMode.REQUIRED) + private String attachmentIds; + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsImportForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsImportForm.java new file mode 100644 index 0000000..379d38b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsImportForm.java @@ -0,0 +1,60 @@ +package net.lab1024.sa.admin.module.service.domain.form; + +import cn.idev.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 服务申报导入表单 + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +@Data +public class ServiceApplicationsImportForm { + + @ExcelProperty("申报律师ID") + private Integer userId; + + @ExcelProperty("律所ID") + private Integer firmId; + + @ExcelProperty("服务开始时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime serviceStart; + + @ExcelProperty("服务结束时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime serviceEnd; + + @ExcelProperty("服务时长") + private BigDecimal serviceDuration; + + @ExcelProperty("受益人数") + private Integer beneficiaryCount; + + @ExcelProperty("组织单位名称") + private String organizerName; + + @ExcelProperty("负责人姓名") + private String organizerContact; + + @ExcelProperty("联系方式") + private String organizerPhone; + + @ExcelProperty("服务内容描述") + private String serviceContent; + + @ExcelProperty("执业证号") + private String certificateNumber; + + @ExcelProperty("活动类别") + private String activityCategoryId; + + @ExcelProperty("活动名称") + private String activityNameId; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsQueryForm.java new file mode 100644 index 0000000..edf93de --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsQueryForm.java @@ -0,0 +1,145 @@ +package net.lab1024.sa.admin.module.service.domain.form; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.v3.oas.annotations.media.Schema; +import net.lab1024.sa.base.common.domain.PageParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 服务申报表 分页查询表单 + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@Data +@EqualsAndHashCode(callSuper = false) +public class ServiceApplicationsQueryForm extends PageParam { + /** + * 申报ID + */ + private Integer applicationId; + + /** + * 申报律师ID + */ + private Integer userId; + + /** + * 律所ID + */ + private Integer firmId; + + /** + * 服务开始时间 + */ + private LocalDateTime serviceStart; + + /** + * 服务结束时间 + */ + private LocalDateTime serviceEnd; + + /** + * 服务时长(小时) + */ + private BigDecimal serviceDuration; + + /** + * 受益人数 + */ + private Integer beneficiaryCount; + + /** + * 组织单位名称 + */ + private String organizerName; + + /** + * 负责人姓名 + */ + private String organizerContact; + + /** + * 联系方式 + */ + private String organizerPhone; + + /** + * 服务内容描述 + */ + private String serviceContent; + + /** + * 工作量换算得分 + */ + private BigDecimal workloadScore; + + /** + * 律所审核状态:0-待审核,1-通过,2-退回 + */ + private Integer firmAuditStatus; + + /** + * 律所审核意见 + */ + private String firmAuditOpinion; + + /** + * 律所审核人 + */ + private Integer firmAuditUser; + + /** + * 律所审核时间 + */ + private LocalDateTime firmAuditTime; + + /** + * 协会审核状态:0-待审核,1-通过,2-退回 + */ + private Integer associationAuditStatus; + + /** + * 协会审核意见 + */ + private String associationAuditOpinion; + + /** + * 协会审核人 + */ + private Integer associationAuditUser; + + /** + * 协会审核时间 + */ + private LocalDateTime associationAuditTime; + + /** + * 备案编号 + */ + private String recordNo; + + /** + * 备案状态:0-未备案,1-已备案 + */ + private Integer recordStatus; + + /** + * 备案时间 + */ + private LocalDateTime recordTime; + + private String certificateNumber; + + private String activityCategoryId; + + private String activityNameId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsUpdateForm.java new file mode 100644 index 0000000..1c730f7 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.service.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotNull; +import lombok.Data; + +/** + * 服务申报表 更新表单 + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@Data +public class ServiceApplicationsUpdateForm { + + @Schema(description = "申报ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "申报ID 不能为空") + private Integer applicationId; + + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ActivityCategoryConverter.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ActivityCategoryConverter.java new file mode 100644 index 0000000..5dbfc33 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ActivityCategoryConverter.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.admin.module.service.domain.vo; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ReadConverterContext; +import com.alibaba.excel.converters.WriteConverterContext; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 活动类别转换器 + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +public class ActivityCategoryConverter implements Converter { + + // 缓存类别名称到ID的映射 + private static Map categoryNameToIdMap = new ConcurrentHashMap<>(); + + // 更新缓存 + public static void updateCategoryCache(List categoryList) { + categoryNameToIdMap.clear(); + for (CategoryEntity category : categoryList) { + categoryNameToIdMap.put(category.getCategoryName(), String.valueOf(category.getCategoryId())); + } + } + + @Override + public Class supportJavaTypeKey() { + return String.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + String categoryName = cellData.getStringValue(); + if (categoryName != null && !categoryName.trim().isEmpty()) { + // 尝试从缓存中获取对应的ID + String categoryId = categoryNameToIdMap.get(categoryName); + if (categoryId != null) { + return categoryId; + } + } + return categoryName; // 如果找不到对应的ID,返回原始值 + } + + @Override + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + // 从ID转换回名称(用于导出) + if (value != null) { + for (Map.Entry entry : categoryNameToIdMap.entrySet()) { + if (value.equals(entry.getValue())) { + return new WriteCellData<>(entry.getKey()); + } + } + } + return new WriteCellData<>(value); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ActivityNameConverter.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ActivityNameConverter.java new file mode 100644 index 0000000..b25863a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ActivityNameConverter.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.admin.module.service.domain.vo; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 活动名称转换器 + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +public class ActivityNameConverter implements Converter { + + // 缓存活动名称到ID的映射 + private static Map activityNameToIdMap = new ConcurrentHashMap<>(); + + // 更新缓存 + public static void updateActivityCache(List goodsList) { + activityNameToIdMap.clear(); + for (GoodsEntity goods : goodsList) { + activityNameToIdMap.put(goods.getGoodsName(), String.valueOf(goods.getGoodsId())); + } + } + + @Override + public Class supportJavaTypeKey() { + return String.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + String activityName = cellData.getStringValue(); + if (activityName != null && !activityName.trim().isEmpty()) { + // 尝试从缓存中获取对应的ID + String activityId = activityNameToIdMap.get(activityName); + if (activityId != null) { + return activityId; + } + } + return activityName; // 如果找不到对应的ID,返回原始值 + } + + @Override + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + // 从ID转换回名称(用于导出) + if (value != null) { + for (Map.Entry entry : activityNameToIdMap.entrySet()) { + if (value.equals(entry.getValue())) { + return new WriteCellData<>(entry.getKey()); + } + } + } + return new WriteCellData<>(value); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/EmployeeNameConverter.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/EmployeeNameConverter.java new file mode 100644 index 0000000..f6732b9 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/EmployeeNameConverter.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.admin.module.service.domain.vo; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 员工姓名转换器 + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +public class EmployeeNameConverter implements Converter { + + // 缓存员工姓名到ID的映射 + private static Map employeeNameToIdMap = new ConcurrentHashMap<>(); + + // 更新缓存 + public static void updateEmployeeNameCache(List employeeList) { + employeeNameToIdMap.clear(); + for (EmployeeEntity employee : employeeList) { + employeeNameToIdMap.put(employee.getActualName(), employee.getEmployeeId()); + } + } + + @Override + public Class supportJavaTypeKey() { + return String.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + String employeeName = cellData.getStringValue(); + if (employeeName != null && !employeeName.trim().isEmpty()) { + // 尝试从缓存中获取对应的ID + Long employeeId = employeeNameToIdMap.get(employeeName); + if (employeeId != null) { + return String.valueOf(employeeId); + } + } + return employeeName; // 如果找不到对应的ID,返回原始值 + } + + @Override + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + // 从ID转换回姓名(用于导出) + if (value != null) { + for (Map.Entry entry : employeeNameToIdMap.entrySet()) { + if (value.equals(String.valueOf(entry.getValue()))) { + return new WriteCellData<>(entry.getKey()); + } + } + } + return new WriteCellData<>(value); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/OrganizationNameConverter.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/OrganizationNameConverter.java new file mode 100644 index 0000000..9f64e15 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/OrganizationNameConverter.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.admin.module.service.domain.vo; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 机构名称转换器 + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +public class OrganizationNameConverter implements Converter { + + // 缓存机构名称到ID的映射 + private static Map organizationNameToIdMap = new ConcurrentHashMap<>(); + + // 更新缓存 + public static void updateOrganizationNameCache(List departmentList) { + organizationNameToIdMap.clear(); + for (DepartmentEntity department : departmentList) { + organizationNameToIdMap.put(department.getDepartmentName(), department.getDepartmentId()); + } + } + + @Override + public Class supportJavaTypeKey() { + return String.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + String organizationName = cellData.getStringValue(); + if (organizationName != null && !organizationName.trim().isEmpty()) { + // 尝试从缓存中获取对应的ID + Long organizationId = organizationNameToIdMap.get(organizationName); + if (organizationId != null) { + return String.valueOf(organizationId); + } + } + return organizationName; // 如果找不到对应的ID,返回原始值 + } + + @Override + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + // 从ID转换回机构名称(用于导出) + if (value != null) { + for (Map.Entry entry : organizationNameToIdMap.entrySet()) { + if (value.equals(String.valueOf(entry.getValue()))) { + return new WriteCellData<>(entry.getKey()); + } + } + } + return new WriteCellData<>(value); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsTemplateVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsTemplateVO.java new file mode 100644 index 0000000..5856dcc --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsTemplateVO.java @@ -0,0 +1,79 @@ +package net.lab1024.sa.admin.module.service.domain.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; + +/** + * 服务申报Excel模板VO + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +@Data +@ColumnWidth(15) // 设置默认列宽 +@HeadRowHeight(20) +public class ServiceApplicationsTemplateVO { + + @ExcelProperty(value = "姓名", converter = EmployeeNameConverter.class) + @ColumnWidth(15) + private String userId; + + @ExcelProperty("执业证号") + @ColumnWidth(20) + private String licenseNumber; + + @ExcelProperty(value = "执业机构", converter = OrganizationNameConverter.class) + @ColumnWidth(20) + private String firmId; + + @ExcelProperty(value = "活动类别", converter = ActivityCategoryConverter.class) + @ColumnWidth(15) + private String activityCategoryId; + + @ExcelProperty(value = "活动名称", converter = ActivityNameConverter.class) + @ColumnWidth(15) + private String activityNameId; + + @ExcelProperty("受益人数") + @ColumnWidth(10) + private Integer beneficiaryCount; + + @ExcelProperty(value = "开始时间") + @ColumnWidth(20) + private LocalDateTime serviceStart; + + @ExcelProperty(value = "结束时间") + @ColumnWidth(20) + private LocalDateTime serviceEnd; + + /* @ExcelProperty(value = "填报时间") + @ColumnWidth(20) + private LocalDateTime reportTime;*/ + + @ExcelProperty("服务时长") + @ColumnWidth(10) + private Double serviceDuration; + + @ExcelProperty("组织单位名称") + @ColumnWidth(25) + private String organizerName; + + @ExcelProperty("负责人姓名") + @ColumnWidth(15) + private String organizerContact; + + @ExcelProperty("联系方式") + @ColumnWidth(15) + private String organizerPhone; + + @ExcelProperty("服务内容") + @ColumnWidth(30) + private String serviceContent; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsVO.java new file mode 100644 index 0000000..a7cdecc --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsVO.java @@ -0,0 +1,114 @@ +package net.lab1024.sa.admin.module.service.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 服务申报表 列表VO + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ + +@Data +public class ServiceApplicationsVO { + @Schema(description = "申报ID") + private Long applicationId; + + @Schema(description = "申报律师") + private Long userId; + + @Schema(description = "律所") + private Long firmId; + + @Schema(description = "律所名称") + private String departmentName; + + @Schema(description = "律师名称") + private String userName; + @Schema(description = "服务开始时间") + private LocalDateTime serviceStart; + + @Schema(description = "服务结束时间") + private LocalDateTime serviceEnd; + + @Schema(description = "服务时长(小时)") + private BigDecimal serviceDuration; + + @Schema(description = "受益人数") + private Integer beneficiaryCount; + + @Schema(description = "组织单位名称") + private String organizerName; + + @Schema(description = "负责人姓名") + private String organizerContact; + + @Schema(description = "联系方式") + private String organizerPhone; + + @Schema(description = "服务内容描述") + private String serviceContent; + + @Schema(description = "工作量换算得分") + private BigDecimal workloadScore; + + @Schema(description = "律所审核状态:0-待审核,1-审核中,2-通过,3-拒绝") + private Integer firmAuditStatus; + + @Schema(description = "律所审核意见") + private String firmAuditOpinion; + + @Schema(description = "律所审核人") + private Integer firmAuditUser; + + @Schema(description = "律所审核时间") + private LocalDateTime firmAuditTime; + + @Schema(description = "协会审核状态:0-待审核,1-审核中,2-通过,3-拒绝") + private Integer associationAuditStatus; + + @Schema(description = "协会审核意见") + private String associationAuditOpinion; + + @Schema(description = "协会审核人") + private Integer associationAuditUser; + + @Schema(description = "协会审核时间") + private LocalDateTime associationAuditTime; + + @Schema(description = "备案编号") + private String recordNo; + + @Schema(description = "备案状态:0-未备案,1-已备案") + private Integer recordStatus; + + @Schema(description = "备案时间") + private LocalDateTime recordTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "职业证号") + private String certificateNumber; + + @NotBlank(message = "活动类别 ") + private String activityCategory; + + @NotBlank(message = "活动名称 ") + private String activityName; + + @NotBlank(message = "活动类别id ") + private Long activityCategoryId; + + @NotBlank(message = "活动名称id ") + private Long activityNameId; + + @Schema(description = "附件id集合") + private String attachmentIds; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/manager/ServiceApplicationsManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/manager/ServiceApplicationsManager.java new file mode 100644 index 0000000..5582728 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/manager/ServiceApplicationsManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.service.manager; + +import net.lab1024.sa.admin.module.service.dao.ServiceApplicationsDao; +import net.lab1024.sa.admin.module.service.domain.entity.ServiceApplicationsEntity; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 服务申报表 Manager + * + * @Author wzh + * @Date 2025-12-20 14:44:06 + * @Copyright 1.0 + */ +@Service +public class ServiceApplicationsManager extends ServiceImpl { + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsDataListener.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsDataListener.java new file mode 100644 index 0000000..dbaf724 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsDataListener.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.admin.module.service.service; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsImportForm; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 服务申报导入Excel监听器 + * + * @Author wzh + * @Date 2025-12-23 + * @Copyright 1.0 + */ +public class ServiceApplicationsDataListener extends AnalysisEventListener { + + private List dataList = new ArrayList<>(); + + @Override + public void invoke(ServiceApplicationsImportForm data, AnalysisContext context) { + // 每读取一行数据就添加到集合中 + dataList.add(data); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 所有数据解析完成后的处理 + } + + public List getDataList() { + return dataList; + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java new file mode 100644 index 0000000..35ec67a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java @@ -0,0 +1,542 @@ +package net.lab1024.sa.admin.module.service.service; + +import cn.idev.excel.FastExcel; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.common.enums.ReviewEnum; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.service.CategoryService; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; +import net.lab1024.sa.admin.module.business.goods.service.GoodsService; +import net.lab1024.sa.admin.module.service.dao.ServiceApplicationsDao; +import net.lab1024.sa.admin.module.service.domain.entity.ServiceApplicationsEntity; +import net.lab1024.sa.admin.module.service.domain.form.*; +import net.lab1024.sa.admin.module.service.domain.vo.ActivityCategoryConverter; +import net.lab1024.sa.admin.module.service.domain.vo.ActivityNameConverter; +import net.lab1024.sa.admin.module.service.domain.vo.EmployeeNameConverter; +import net.lab1024.sa.admin.module.service.domain.vo.OrganizationNameConverter; +import net.lab1024.sa.admin.module.service.domain.vo.ServiceApplicationsTemplateVO; +import net.lab1024.sa.admin.module.service.domain.vo.ServiceApplicationsVO; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.admin.util.AdminRequestUtil; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.exception.BusinessException; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.util.SmartResponseUtil; +import org.apache.catalina.util.RequestUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 服务申报 Service + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +@Slf4j +@Service +public class ServiceApplicationsService { + + @Resource + private ServiceApplicationsDao serviceApplicationsDao; + + @Resource + private EmployeeService employeeService; + + @Resource + private DepartmentService departmentService; + + @Resource + private CategoryService categoryService; + + @Resource + private GoodsService goodsService; + + /** + * 分页查询 + */ + public PageResult queryPage(ServiceApplicationsQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = serviceApplicationsDao.queryPage(page, queryForm); + if (!CollectionUtils.isEmpty(list)) { + //翻译单位名称和用户名称 + list.forEach(item -> { + item.setDepartmentName(departmentService.queryByFirmId(item.getFirmId()).getDepartmentName()); // Fixed method call + item.setUserName(employeeService.queryById(item.getUserId()).getActualName()); + item.setActivityCategory(categoryService.queryById(item.getActivityCategoryId()).getCategoryName()); + item.setActivityName(goodsService.queryById(item.getActivityNameId()).getGoodsName()); + }); + } + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + */ + public ResponseDTO add(ServiceApplicationsAddForm addForm) { + ServiceApplicationsEntity serviceApplicationsEntity = SmartBeanUtil.copy(addForm, ServiceApplicationsEntity.class); + serviceApplicationsDao.insert(serviceApplicationsEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + */ + public ResponseDTO update(ServiceApplicationsUpdateForm updateForm) { + ServiceApplicationsEntity serviceApplicationsEntity = SmartBeanUtil.copy(updateForm, ServiceApplicationsEntity.class); + //serviceApplicationsEntity.setFirmAuditStatus(ReviewEnum.APPROVAL.getValue()); + serviceApplicationsDao.updateById(serviceApplicationsEntity); + return ResponseDTO.ok(); + } + + /** + * 提交 + * + */ + public ResponseDTO submit(Integer applicationId) { + if (null == applicationId){ + return ResponseDTO.ok(); + } + ServiceApplicationsEntity serviceApplicationsEntity = serviceApplicationsDao.selectById(applicationId); + serviceApplicationsEntity.setFirmAuditStatus(ReviewEnum.APPROVAL.getValue()); + + serviceApplicationsDao.updateById(serviceApplicationsEntity); + return ResponseDTO.ok(); + } + /** + * 批量删除 + */ + public ResponseDTO batchDelete(List idList) { + if (CollectionUtils.isEmpty(idList)){ + return ResponseDTO.ok(); + } + + serviceApplicationsDao.batchUpdateDeleted(idList, true); + return ResponseDTO.ok(); + } + + /** + * 单个删除 + */ + public ResponseDTO delete(Integer applicationId) { + if (null == applicationId){ + return ResponseDTO.ok(); + } + + serviceApplicationsDao.updateDeleted(applicationId, true); + return ResponseDTO.ok(); + } + + @Transactional + public ResponseDTO importService(MultipartFile file) { + // 预加载转换器缓存 + List categoryList = categoryService.getAllCategory(); + List goodsList = goodsService.getAllGoods(); + + // 获取当前用户信息 + RequestUser requestUser = AdminRequestUtil.getRequestUser(); + List employeesInDepartment = new ArrayList<>(); + List departmentList = new ArrayList<>(); + + if (requestUser != null) { + EmployeeEntity currentUser = employeeService.queryById(requestUser.getUserId()); + if (currentUser != null) { + // 获取当前用户所在部门的所有员工 + employeesInDepartment = employeeService.getByDepartmentId(currentUser.getDepartmentId()); + // 获取当前用户的部门信息 + DepartmentEntity currentUserDepartment = departmentService.queryByFirmId(currentUser.getDepartmentId()); + if (currentUserDepartment != null) { + departmentList = new ArrayList<>(); + departmentList.add(currentUserDepartment); + } + } + } + + // 更新转换器缓存 + ActivityCategoryConverter.updateCategoryCache(categoryList); + ActivityNameConverter.updateActivityCache(goodsList); + EmployeeNameConverter.updateEmployeeNameCache(employeesInDepartment); + OrganizationNameConverter.updateOrganizationNameCache(departmentList); + + List dataList; + try { + dataList = EasyExcel.read(file.getInputStream()).head(ServiceApplicationsTemplateVO.class) + .sheet() + .doReadSync(); + } catch (IOException e) { + throw new BusinessException("数据格式存在问题,无法读取"); + } + + if (CollectionUtils.isEmpty(dataList)) { + return ResponseDTO.userErrorParam("数据为空"); + } + + // 将导入的数据转换为实体对象并保存到数据库 + List entityList = dataList.stream() + .map(this::convertImportFormToEntity) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 批量插入数据到数据库 + if (!CollectionUtils.isEmpty(entityList)) { + for (ServiceApplicationsEntity serviceApplicationsEntity : entityList) { + serviceApplicationsDao.insert(serviceApplicationsEntity); + } + } + + return ResponseDTO.okMsg("成功导入" + dataList.size() + "条数据"); + } + + /** + * 将ServiceApplicationsImportForm转换为ServiceApplicationsEntity + */ + private ServiceApplicationsEntity convertImportFormToEntity(ServiceApplicationsTemplateVO form) { + if (form == null) { + return null; + } + + ServiceApplicationsEntity entity = SmartBeanUtil.copy(form, ServiceApplicationsEntity.class); + + return entity; + } + + /** + * 服务申报模板 + */ + public void downloadTemplate(HttpServletResponse response ) { + try { + // 创建模板数据列表 + List templateList = new ArrayList<>(); + + // 添加示例数据作为第一行 + ServiceApplicationsTemplateVO exampleVO = new ServiceApplicationsTemplateVO(); + exampleVO.setUserId("张三"); + exampleVO.setLicenseNumber("A202101234567"); + exampleVO.setFirmId("北京市第一律师事务所"); + exampleVO.setActivityCategoryId("公益活动"); // 这个值会通过下拉框选择 + exampleVO.setActivityNameId("法律咨询"); // 这个值会通过下拉框选择 + exampleVO.setBeneficiaryCount(50); + exampleVO.setServiceStart(LocalDateTime.of(2025, 1, 15, 9, 0, 0)); + exampleVO.setServiceEnd(LocalDateTime.of(2025, 1, 15, 17, 0, 0)); + //exampleVO.setReportTime(LocalDateTime.now()); + exampleVO.setServiceDuration(8.0); + exampleVO.setOrganizerName("北京市司法局"); + exampleVO.setOrganizerContact("李主任"); + exampleVO.setOrganizerPhone("010-12345678"); + exampleVO.setServiceContent("提供免费法律咨询服务"); + templateList.add(exampleVO); + + RequestUser requestUser = AdminRequestUtil.getRequestUser(); + // 如果有用户信息,则预填充用户相关信息 + if (requestUser != null) { + ServiceApplicationsTemplateVO templateVO = new ServiceApplicationsTemplateVO(); + // 预填充用户信息(根据实际业务需要) + EmployeeEntity employeeEntity = employeeService.queryById(requestUser.getUserId()); + templateVO.setUserId(employeeEntity.getActualName()); + templateVO.setFirmId(departmentService.queryByFirmId(employeeEntity.getDepartmentId()).getDepartmentName()); + templateList.add(templateVO); + } + + // 设置下载响应头 + SmartResponseUtil.setDownloadFileHeader(response, "服务申报模板.xlsx"); + + // 获取数据库中的活动类别和活动名称数据 + List categoryList = categoryService.getAllCategory(); + List goodsList = goodsService.getAllGoods(); + + // 提取名称列表用于下拉框 + List categoryNames = categoryList.stream() + .map(CategoryEntity::getCategoryName) + .collect(Collectors.toList()); + + List goodsNames = goodsList.stream() + .map(GoodsEntity::getGoodsName) + .collect(Collectors.toList()); + + // 获取当前用户相关数据用于下拉列表 + List organizationNames = new ArrayList<>(); + List employeeNames = new ArrayList<>(); + + if (requestUser != null) { + // 获取当前用户所在机构 + EmployeeEntity currentUser = employeeService.queryById(requestUser.getUserId()); + if (currentUser != null) { + // 当前用户的机构名称 + String currentUserOrganization = departmentService.queryByFirmId(currentUser.getDepartmentId()).getDepartmentName(); + organizationNames.add(currentUserOrganization); + + // 获取当前机构下的所有员工 + List employeesInDepartment = employeeService.getByDepartmentId(currentUser.getDepartmentId()); + if (employeesInDepartment != null) { + employeeNames = employeesInDepartment.stream() + .map(EmployeeEntity::getActualName) + .collect(Collectors.toList()); + } + } + } + + // 导出Excel模板,带下拉选项 + EasyExcel.write(response.getOutputStream(), ServiceApplicationsTemplateVO.class) + .autoCloseStream(false) + .sheet("服务申报模板") + .registerWriteHandler(new DropdownSheetWriteHandler(categoryNames, goodsNames, organizationNames, employeeNames)) + .doWrite(templateList); + } catch (Exception e) { + log.error("模板下载失败", e); + throw new BusinessException("模板下载失败:" + (e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName() + " occurred")); + } + } + + public ResponseDTO batchSubmit(List idList) { + if (CollectionUtils.isEmpty(idList)){ + return ResponseDTO.ok(); + } + + serviceApplicationsDao.batchSubmit(idList, ReviewEnum.APPROVAL.getValue()); + return ResponseDTO.ok(); + } + + /** + * Excel下拉列表处理器 + */ + public static class DropdownSheetWriteHandler implements SheetWriteHandler { + + private final List categoryNames; + private final List goodsNames; + private final List organizationNames; + private final List employeeNames; + + public DropdownSheetWriteHandler(List categoryNames, List goodsNames, List organizationNames, List employeeNames) { + this.categoryNames = categoryNames; + this.goodsNames = goodsNames; + this.organizationNames = organizationNames; + this.employeeNames = employeeNames; + } + + @Override + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + Sheet sheet = writeSheetHolder.getSheet(); + Workbook workbook = writeWorkbookHolder.getWorkbook(); + + DataValidationHelper validationHelper = sheet.getDataValidationHelper(); + + // 为活动类别列创建下拉列表 (D列,索引为3) - 在ServiceApplicationsTemplateVO中是第4个字段 + if (categoryNames != null && !categoryNames.isEmpty()) { + try { + // 创建隐藏的辅助Sheet来存储下拉选项 + Sheet hiddenSheet = null; + try { + hiddenSheet = workbook.getSheet("HiddenOptions"); + } catch (Exception e) { + // 如果获取不到,创建新的辅助工作表 + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 如果hiddenSheet仍然为null,创建一个新的 + if (hiddenSheet == null) { + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 在辅助Sheet中创建类别选项 + Row categoryRow = hiddenSheet.createRow(0); + for (int i = 0; i < Math.min(categoryNames.size(), 50); i++) { // 限制选项数量防止Excel限制 + Cell cell = categoryRow.createCell(i); + cell.setCellValue(categoryNames.get(i)); + } + + // 创建名称定义 + Name categoryListName = workbook.createName(); + categoryListName.setNameName("CategoryList"); + // 修正公式,确保正确引用范围 + int lastColIndex = Math.min(categoryNames.size() - 1, 49); + char lastColChar = (char)('A' + lastColIndex); + String categoryFormula = "HiddenOptions!$A$1:$" + lastColChar + "$1"; + categoryListName.setRefersToFormula(categoryFormula); + + // 创建数据验证 + DataValidationConstraint constraint = validationHelper.createFormulaListConstraint("CategoryList"); + CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, 3, 3); // D列是索引3 + DataValidation validation = validationHelper.createValidation(constraint, addressList); + validation.setShowErrorBox(true); + validation.setEmptyCellAllowed(true); + sheet.addValidationData(validation); + } catch (Exception e) { + log.error("创建活动类别下拉列表失败", e); + } + } + + // 为活动名称列创建下拉列表 (E列,索引为4) - 在ServiceApplicationsTemplateVO中是第5个字段 + if (goodsNames != null && !goodsNames.isEmpty()) { + try { + // 使用同一个辅助Sheet来存储活动名称选项 + Sheet hiddenSheet = null; + try { + hiddenSheet = workbook.getSheet("HiddenOptions"); + } catch (Exception e) { + // 如果获取不到,创建新的辅助工作表 + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 如果hiddenSheet仍然为null,创建一个新的 + if (hiddenSheet == null) { + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 在辅助Sheet中创建商品选项(使用第二行) + Row goodsRow = hiddenSheet.createRow(1); + for (int i = 0; i < Math.min(goodsNames.size(), 50); i++) { // 限制选项数量防止Excel限制 + Cell cell = goodsRow.createCell(i); + cell.setCellValue(goodsNames.get(i)); + } + + // 创建名称定义 + Name goodsListName = workbook.createName(); + goodsListName.setNameName("GoodsList"); + // 修正公式,确保正确引用范围 + int lastColIndex = Math.min(goodsNames.size() - 1, 49); + char lastColChar = (char)('A' + lastColIndex); + String goodsFormula = "HiddenOptions!$A$2:$" + lastColChar + "$2"; + goodsListName.setRefersToFormula(goodsFormula); + + // 创建数据验证 + DataValidationConstraint constraint = validationHelper.createFormulaListConstraint("GoodsList"); + CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, 4, 4); // E列是索引4 + DataValidation validation = validationHelper.createValidation(constraint, addressList); + validation.setShowErrorBox(true); + validation.setEmptyCellAllowed(true); + sheet.addValidationData(validation); + } catch (Exception e) { + log.error("创建活动名称下拉列表失败", e); + } + } + + // 为执业机构列创建下拉列表 (C列,索引为2) - 在ServiceApplicationsTemplateVO中是第3个字段 + if (organizationNames != null && !organizationNames.isEmpty()) { + try { + // 使用同一个辅助Sheet来存储机构名称选项 + Sheet hiddenSheet = null; + try { + hiddenSheet = workbook.getSheet("HiddenOptions"); + } catch (Exception e) { + // 如果获取不到,创建新的辅助工作表 + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 如果hiddenSheet仍然为null,创建一个新的 + if (hiddenSheet == null) { + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 在辅助Sheet中创建机构选项(使用第三行) + Row orgRow = hiddenSheet.createRow(2); + for (int i = 0; i < Math.min(organizationNames.size(), 50); i++) { // 限制选项数量防止Excel限制 + Cell cell = orgRow.createCell(i); + cell.setCellValue(organizationNames.get(i)); + } + + // 创建名称定义 + Name orgListName = workbook.createName(); + orgListName.setNameName("OrgList"); + // 修正公式,确保正确引用范围 + int lastColIndex = Math.min(organizationNames.size() - 1, 49); + char lastColChar = (char)('A' + lastColIndex); + String orgFormula = "HiddenOptions!$A$3:$" + lastColChar + "$3"; + orgListName.setRefersToFormula(orgFormula); + + // 创建数据验证 + DataValidationConstraint constraint = validationHelper.createFormulaListConstraint("OrgList"); + CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, 2, 2); // C列是索引2 + DataValidation validation = validationHelper.createValidation(constraint, addressList); + validation.setShowErrorBox(true); + validation.setEmptyCellAllowed(true); + sheet.addValidationData(validation); + } catch (Exception e) { + log.error("创建执业机构下拉列表失败", e); + } + } + + // 为姓名列创建下拉列表 (A列,索引为0) - 在ServiceApplicationsTemplateVO中是第1个字段 + if (employeeNames != null && !employeeNames.isEmpty()) { + try { + // 使用同一个辅助Sheet来存储员工姓名选项 + Sheet hiddenSheet = null; + try { + hiddenSheet = workbook.getSheet("HiddenOptions"); + } catch (Exception e) { + // 如果获取不到,创建新的辅助工作表 + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 如果hiddenSheet仍然为null,创建一个新的 + if (hiddenSheet == null) { + hiddenSheet = workbook.createSheet("HiddenOptions"); + workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true); // 隐藏辅助工作表 + } + + // 在辅助Sheet中创建员工姓名选项(使用第四行) + Row empRow = hiddenSheet.createRow(3); + for (int i = 0; i < Math.min(employeeNames.size(), 50); i++) { // 限制选项数量防止Excel限制 + Cell cell = empRow.createCell(i); + cell.setCellValue(employeeNames.get(i)); + } + + // 创建名称定义 + Name empListName = workbook.createName(); + empListName.setNameName("EmpList"); + // 修正公式,确保正确引用范围 + int lastColIndex = Math.min(employeeNames.size() - 1, 49); + char lastColChar = (char)('A' + lastColIndex); + String empFormula = "HiddenOptions!$A$4:$" + lastColChar + "$4"; + empListName.setRefersToFormula(empFormula); + + // 创建数据验证 + DataValidationConstraint constraint = validationHelper.createFormulaListConstraint("EmpList"); + CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, 0, 0); // A列是索引0 + DataValidation validation = validationHelper.createValidation(constraint, addressList); + validation.setShowErrorBox(true); + validation.setEmptyCellAllowed(true); + sheet.addValidationData(validation); + } catch (Exception e) { + log.error("创建姓名下拉列表失败", e); + } + } + } + + @Override + public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + // 在创建Sheet前执行的逻辑,这里不需要处理 + } + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java new file mode 100644 index 0000000..c8aac32 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.system.datascope; + + +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.strategy.AbstractDataScopeStrategy; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据范围 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface DataScope { + + DataScopeTypeEnum dataScopeType() ; + + DataScopeWhereInTypeEnum whereInType() default DataScopeWhereInTypeEnum.EMPLOYEE; + + /** + * DataScopeWhereInTypeEnum.CUSTOM_STRATEGY类型 才可使用joinSqlImplClazz属性 + */ + Class joinSqlImplClazz() default AbstractDataScopeStrategy.class; + + /** + * 多个参数已逗号分隔,本属性主要用于joinSqlImplClazz 实现类跟进参数进行不同的范围控制,如不使用CUSTOM_STRATEGY,可不做配置 + */ + String paramName() default ""; + /** + * + * 第几个where 条件 从0开始 + */ + int whereIndex() default 0; + + /** + * DataScopeWhereInTypeEnum为CUSTOM_STRATEGY类型时,此属性无效 + */ + String joinSql() default ""; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java new file mode 100644 index 0000000..2962490 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java @@ -0,0 +1,180 @@ +package net.lab1024.sa.admin.module.system.datascope; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Maps; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; +import net.lab1024.sa.admin.module.system.datascope.service.DataScopeSqlConfigService; +import net.lab1024.sa.base.common.domain.DataScopePlugin; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.mapping.*; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Plugin; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * mybaits sql 拦截 + */ +@Intercepts({@Signature(type = org.apache.ibatis.executor.Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) +@Component +public class MyBatisPlugin extends DataScopePlugin { + + @Resource + private ApplicationContext applicationContext; + + @Override + public Object intercept(Invocation invocation) throws Throwable { + + MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; + Object parameter = invocation.getArgs()[1]; + + BoundSql boundSql = mappedStatement.getBoundSql(parameter); + String originalSql = boundSql.getSql().trim(); + String id = mappedStatement.getId(); + List methodStrList = StrUtil.split(id, "."); + String path = methodStrList.get(methodStrList.size() - 2) + "." + methodStrList.get(methodStrList.size() - 1); + DataScopeSqlConfigService dataScopeSqlConfigService = this.dataScopeSqlConfigService(); + if (dataScopeSqlConfigService == null) { + return invocation.proceed(); + } + DataScopeSqlConfig sqlConfigDTO = dataScopeSqlConfigService.getSqlConfig(path); + if (sqlConfigDTO != null) { + Map paramMap = this.getParamList(sqlConfigDTO.getParamName(), parameter); + BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, this.joinSql(originalSql, paramMap, sqlConfigDTO)); + ParameterMap map = mappedStatement.getParameterMap(); + MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql), map); + invocation.getArgs()[0] = newMs; + } + + Object obj = invocation.proceed(); + return obj; + } + + + private Map getParamList(String paramName, Object parameter) { + Map paramMap = Maps.newHashMap(); + if (StringUtils.isEmpty(paramName)) { + return paramMap; + } + if (parameter == null) { + return paramMap; + } + if (parameter instanceof Map) { + String[] paramNameArray = paramName.split(","); + Map parameterMap = (Map) parameter; + for (String param : paramNameArray) { + if(parameterMap.containsKey(param)){ + paramMap.put(param, parameterMap.get(param)); + } + } + } + return paramMap; + } + + private String joinSql(String sql, Map paramMap, DataScopeSqlConfig sqlConfigDTO) { + if (null == sqlConfigDTO) { + return sql; + } + String appendSql = this.dataScopeSqlConfigService().getJoinSql(paramMap, sqlConfigDTO); + if (StringUtils.isEmpty(appendSql)) { + return sql; + } + Integer appendSqlWhereIndex = sqlConfigDTO.getWhereIndex(); + String where = "where"; + String order = "order by"; + String group = "group by"; + int whereIndex = StringUtils.ordinalIndexOf(sql.toLowerCase(), where, appendSqlWhereIndex + 1); + int orderIndex = sql.toLowerCase().indexOf(order); + int groupIndex = sql.toLowerCase().indexOf(group); + if (whereIndex > -1) { + String subSql = sql.substring(0, whereIndex + where.length() + 1); + subSql = subSql + " " + appendSql + " AND " + sql.substring(whereIndex + where.length() + 1); + return subSql; + } + + if (groupIndex > -1) { + String subSql = sql.substring(0, groupIndex); + subSql = subSql + " where " + appendSql + " " + sql.substring(groupIndex); + return subSql; + } + if (orderIndex > -1) { + String subSql = sql.substring(0, orderIndex); + subSql = subSql + " where " + appendSql + " " + sql.substring(orderIndex); + return subSql; + } + sql += " where " + appendSql; + return sql; + } + + public DataScopeSqlConfigService dataScopeSqlConfigService() { + return (DataScopeSqlConfigService) applicationContext.getBean("dataScopeSqlConfigService"); + } + + public class BoundSqlSqlSource implements SqlSource { + + BoundSql boundSql; + + public BoundSqlSqlSource(BoundSql boundSql) { + this.boundSql = boundSql; + } + + @Override + public BoundSql getBoundSql(Object parameterObject) { + return boundSql; + } + } + + /** + * 复制MappedStatement对象 + */ + private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource, ParameterMap parameterMap) { + + MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType()); + builder.resource(ms.getResource()); + builder.fetchSize(ms.getFetchSize()); + builder.statementType(ms.getStatementType()); + builder.keyGenerator(ms.getKeyGenerator()); + builder.timeout(ms.getTimeout()); + builder.parameterMap(parameterMap); + builder.resultMaps(ms.getResultMaps()); + builder.resultSetType(ms.getResultSetType()); + builder.cache(ms.getCache()); + builder.flushCacheRequired(ms.isFlushCacheRequired()); + builder.useCache(ms.isUseCache()); + return builder.build(); + } + + /** + * 复制BoundSql对象 + */ + private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) { + BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject()); + for (ParameterMapping mapping : boundSql.getParameterMappings()) { + String prop = mapping.getProperty(); + if (boundSql.hasAdditionalParameter(prop)) { + newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop)); + } + } + return newBoundSql; + } + + @Override + public Object plugin(Object arg0) { + return Plugin.wrap(arg0, this); + } + + @Override + public void setProperties(Properties arg0) { + + } + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java new file mode 100644 index 0000000..a2c350c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.admin.module.system.datascope.constant; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 数据范围 类型 + */ +public enum DataScopeTypeEnum implements BaseEnum { + + /** + * 系统通知 + */ + NOTICE(1, 20, "系统通知", "系统通知数据范围"), + ; + + private final Integer value; + + private final Integer sort; + + private final String name; + + private final String desc; + + DataScopeTypeEnum(Integer value, Integer sort, String name, String desc) { + this.value = value; + this.sort = sort; + this.name = name; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + public Integer getSort() { + return sort; + } + + @Override + public String getDesc() { + return desc; + } + + public String getName() { + return name; + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java new file mode 100644 index 0000000..13e73da --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.system.datascope.constant; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + + +/** + * 数据可见范围类型 + */ +public enum DataScopeViewTypeEnum implements BaseEnum { + + /** + * 本人 + */ + ME(0, 0, "本人"), + + /** + * 部门 + */ + DEPARTMENT(1, 5, "本部门"), + + /** + * 本部门及下属子部门 + */ + DEPARTMENT_AND_SUB(2, 10, "本部门及下属子部门"), + + /** + * 全部 + */ + ALL(10, 100, "全部"); + + + + private final Integer value; + private final Integer level; + private final String desc; + + DataScopeViewTypeEnum(Integer value, Integer level, String desc) { + this.value = value; + this.level = level; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + public Integer getLevel() { + return level; + } + + @Override + public String getDesc() { + return desc; + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java new file mode 100644 index 0000000..50c2463 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.system.datascope.constant; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 数据范围 sql where + */ +public enum DataScopeWhereInTypeEnum implements BaseEnum { + + /** + * 以员工IN + */ + EMPLOYEE(0, "以员工IN"), + + /** + * 以部门IN + */ + DEPARTMENT(1, "以部门IN"), + + /** + * 自定义策略 + */ + CUSTOM_STRATEGY(2, "自定义策略"); + + private final Integer value; + private final String desc; + + DataScopeWhereInTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/controller/DataScopeController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/controller/DataScopeController.java new file mode 100644 index 0000000..52d7374 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/controller/DataScopeController.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.admin.module.system.datascope.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeAndViewTypeVO; +import net.lab1024.sa.admin.module.system.datascope.service.DataScopeService; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 查询支持的数据范围类型 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_DATA_SCOPE) +public class DataScopeController { + + @Resource + private DataScopeService dataScopeService; + + @Operation(summary = "获取当前系统所配置的所有数据范围") + @GetMapping("/dataScope/list") + public ResponseDTO> dataScopeList() { + return dataScopeService.dataScopeList(); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java new file mode 100644 index 0000000..62fc097 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 数据范围 + */ +@Data +public class DataScopeAndViewTypeVO { + + @Schema(description = "数据范围类型") + private Integer dataScopeType; + + @Schema(description = "数据范围名称") + private String dataScopeTypeName; + + @Schema(description = "描述") + private String dataScopeTypeDesc; + + @Schema(description = "顺序") + private Integer dataScopeTypeSort; + + @Schema(description = "可见范围列表") + private List viewTypeList; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java new file mode 100644 index 0000000..4f50c56 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +/** + * 数据范围 + */ +@Data +@Builder +public class DataScopeDTO { + + @Schema(description = "数据范围类型") + private Integer dataScopeType; + + @Schema(description = "数据范围名称") + private String dataScopeTypeName; + + @Schema(description = "描述") + private String dataScopeTypeDesc; + + @Schema(description = "顺序") + private Integer dataScopeTypeSort; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java new file mode 100644 index 0000000..4659403 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import lombok.Data; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; + +/** + * 数据范围 + */ +@Data +public class DataScopeSqlConfig { + + /** + * 数据范围类型 + * {@link DataScopeTypeEnum} + */ + private DataScopeTypeEnum dataScopeType; + + /** + * join sql 具体实现类 + */ + private Class joinSqlImplClazz; + + private String joinSql; + + private Integer whereIndex; + + private String paramName; + + /** + * whereIn类型 + * {@link DataScopeWhereInTypeEnum} + */ + private DataScopeWhereInTypeEnum dataScopeWhereInType; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java new file mode 100644 index 0000000..2bf8f5f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +/** + * 数据可见范围 + */ +@Data +@Builder +public class DataScopeViewTypeVO { + + @Schema(description = "可见范围") + private Integer viewType; + + @Schema(description = "可见范围名称") + private String viewTypeName; + + @Schema(description = "级别,用于表示范围大小") + private Integer viewTypeLevel; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java new file mode 100644 index 0000000..bba7f1a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java @@ -0,0 +1,65 @@ +package net.lab1024.sa.admin.module.system.datascope.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeAndViewTypeVO; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeDTO; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeViewTypeVO; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; + +/** + * 数据范围 保存 + */ +@Service +public class DataScopeService { + + /** + * 获取所有可以进行数据范围配置的信息 + */ + public ResponseDTO> dataScopeList() { + List dataScopeList = this.getDataScopeType(); + List dataScopeAndTypeList = SmartBeanUtil.copyList(dataScopeList, DataScopeAndViewTypeVO.class); + List typeList = this.getViewType(); + dataScopeAndTypeList.forEach(e -> { + e.setViewTypeList(typeList); + }); + return ResponseDTO.ok(dataScopeAndTypeList); + } + + /** + * 获取当前系统存在的数据可见范围 + */ + public List getViewType() { + List viewTypeList = Lists.newArrayList(); + DataScopeViewTypeEnum[] enums = DataScopeViewTypeEnum.class.getEnumConstants(); + DataScopeViewTypeVO dataScopeViewTypeDTO; + for (DataScopeViewTypeEnum viewTypeEnum : enums) { + dataScopeViewTypeDTO = DataScopeViewTypeVO.builder().viewType(viewTypeEnum.getValue()).viewTypeLevel(viewTypeEnum.getLevel()).viewTypeName(viewTypeEnum.getDesc()).build(); + viewTypeList.add(dataScopeViewTypeDTO); + } + Comparator comparator = (h1, h2) -> h1.getViewTypeLevel().compareTo(h2.getViewTypeLevel()); + viewTypeList.sort(comparator); + return viewTypeList; + } + + public List getDataScopeType() { + List dataScopeTypeList = Lists.newArrayList(); + DataScopeTypeEnum[] enums = DataScopeTypeEnum.class.getEnumConstants(); + DataScopeDTO dataScopeDTO; + for (DataScopeTypeEnum typeEnum : enums) { + dataScopeDTO = + DataScopeDTO.builder().dataScopeType(typeEnum.getValue()).dataScopeTypeDesc(typeEnum.getDesc()).dataScopeTypeName(typeEnum.getName()).dataScopeTypeSort(typeEnum.getSort()).build(); + dataScopeTypeList.add(dataScopeDTO); + } + Comparator comparator = (h1, h2) -> h1.getDataScopeTypeSort().compareTo(h2.getDataScopeTypeSort()); + dataScopeTypeList.sort(comparator); + return dataScopeTypeList; + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java new file mode 100644 index 0000000..1aaec2d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java @@ -0,0 +1,143 @@ +package net.lab1024.sa.admin.module.system.datascope.service; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.AdminApplication; +import net.lab1024.sa.admin.module.system.datascope.DataScope; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; +import net.lab1024.sa.admin.module.system.datascope.strategy.AbstractDataScopeStrategy; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.reflections.Reflections; +import org.reflections.scanners.MethodAnnotationsScanner; +import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * sql配置 + */ +@Slf4j +@Service +public class DataScopeSqlConfigService { + + /** + * 注解joinsql 参数 + */ + private static final String EMPLOYEE_PARAM = "#employeeIds"; + + private static final String DEPARTMENT_PARAM = "#departmentIds"; + + /** + * 用于拼接查看本人数据范围的 SQL + */ + private static final String CREATE_USER_ID_EQUALS = "create_user_id = "; + + private final ConcurrentHashMap dataScopeMethodMap = new ConcurrentHashMap<>(); + + @Resource + private DataScopeViewService dataScopeViewService; + + @Resource + private ApplicationContext applicationContext; + + + @PostConstruct + private void initDataScopeMethodMap() { + this.refreshDataScopeMethodMap(); + } + + /** + * 刷新 所有添加数据范围注解的接口方法配置 + */ + private Map refreshDataScopeMethodMap() { + Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(AdminApplication.COMPONENT_SCAN)).setScanners(new MethodAnnotationsScanner())); + Set methods = reflections.getMethodsAnnotatedWith(DataScope.class); + for (Method method : methods) { + DataScope dataScopeAnnotation = method.getAnnotation(DataScope.class); + if (dataScopeAnnotation != null) { + DataScopeSqlConfig configDTO = new DataScopeSqlConfig(); + configDTO.setDataScopeType(dataScopeAnnotation.dataScopeType()); + configDTO.setJoinSql(dataScopeAnnotation.joinSql()); + configDTO.setWhereIndex(dataScopeAnnotation.whereIndex()); + configDTO.setDataScopeWhereInType(dataScopeAnnotation.whereInType()); + configDTO.setParamName(dataScopeAnnotation.paramName()); + configDTO.setJoinSqlImplClazz(dataScopeAnnotation.joinSqlImplClazz()); + dataScopeMethodMap.put(method.getDeclaringClass().getSimpleName() + "." + method.getName(), configDTO); + } + } + return dataScopeMethodMap; + } + + /** + * 根据调用的方法获取,此方法的配置信息 + */ + public DataScopeSqlConfig getSqlConfig(String method) { + return this.dataScopeMethodMap.get(method); + } + + /** + * 组装需要拼接的sql + */ + public String getJoinSql(Map paramMap, DataScopeSqlConfig sqlConfigDTO) { + Long employeeId = SmartRequestUtil.getRequestUserId(); + if (employeeId == null) { + return ""; + } + + DataScopeTypeEnum dataScopeTypeEnum = sqlConfigDTO.getDataScopeType(); + DataScopeViewTypeEnum viewTypeEnum = dataScopeViewService.getEmployeeDataScopeViewType(dataScopeTypeEnum, employeeId); + + // 数据权限设置为仅本人可见时 直接返回 create_user_id = employeeId + if (DataScopeViewTypeEnum.ME == viewTypeEnum) { + return CREATE_USER_ID_EQUALS + employeeId; + } + + String joinSql = sqlConfigDTO.getJoinSql(); + + if (DataScopeWhereInTypeEnum.CUSTOM_STRATEGY == sqlConfigDTO.getDataScopeWhereInType()) { + Class strategyClass = sqlConfigDTO.getJoinSqlImplClazz(); + if (strategyClass == null) { + log.warn("data scope custom strategy class is null"); + return ""; + } + AbstractDataScopeStrategy powerStrategy = (AbstractDataScopeStrategy) applicationContext.getBean(sqlConfigDTO.getJoinSqlImplClazz()); + if (powerStrategy == null) { + log.warn("data scope custom strategy class:{} ,bean is null", sqlConfigDTO.getJoinSqlImplClazz()); + return ""; + } + return powerStrategy.getCondition(viewTypeEnum, paramMap, sqlConfigDTO); + } + if (DataScopeWhereInTypeEnum.EMPLOYEE == sqlConfigDTO.getDataScopeWhereInType()) { + List canViewEmployeeIds = dataScopeViewService.getCanViewEmployeeId(viewTypeEnum, employeeId); + if (CollectionUtils.isEmpty(canViewEmployeeIds)) { + return ""; + } + String employeeIds = StringUtils.join(canViewEmployeeIds, ","); + String sql = joinSql.replaceAll(EMPLOYEE_PARAM, employeeIds); + return sql; + } + if (DataScopeWhereInTypeEnum.DEPARTMENT == sqlConfigDTO.getDataScopeWhereInType()) { + List canViewDepartmentIds = dataScopeViewService.getCanViewDepartmentId(viewTypeEnum, employeeId); + if (CollectionUtils.isEmpty(canViewDepartmentIds)) { + return ""; + } + String departmentIds = StringUtils.join(canViewDepartmentIds, ","); + String sql = joinSql.replaceAll(DEPARTMENT_PARAM, departmentIds); + return sql; + } + return ""; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java new file mode 100644 index 0000000..87a9c09 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java @@ -0,0 +1,140 @@ +package net.lab1024.sa.admin.module.system.datascope.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.role.dao.RoleDataScopeDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 数据范围 + */ +@Service +public class DataScopeViewService { + + @Resource + private RoleEmployeeDao roleEmployeeDao; + + @Resource + private RoleDataScopeDao roleDataScopeDao; + + @Resource + private EmployeeDao employeeDao; + + @Resource + private DepartmentService departmentService; + + /** + * 获取某人可以查看的所有人员数据 + */ + public List getCanViewEmployeeId(DataScopeViewTypeEnum viewType, Long employeeId) { + if (DataScopeViewTypeEnum.ME == viewType) { + return this.getMeEmployeeIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT == viewType) { + return this.getDepartmentEmployeeIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB == viewType) { + return this.getDepartmentAndSubEmployeeIdList(employeeId); + } + // 可以查看所有员工数据 + return Lists.newArrayList(); + } + + /** + * 获取某人可以查看的所有部门数据 + */ + public List getCanViewDepartmentId(DataScopeViewTypeEnum viewType, Long employeeId) { + if (DataScopeViewTypeEnum.ME == viewType) { + // 数据可见范围类型为本人时 不可以查看任何部门数据 + return Lists.newArrayList(0L); + } + if (DataScopeViewTypeEnum.DEPARTMENT == viewType) { + return this.getMeDepartmentIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB == viewType) { + return this.getDepartmentAndSubIdList(employeeId); + } + // 可以查看所有部门数据 + return Lists.newArrayList(); + } + + public List getMeDepartmentIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + return Lists.newArrayList(employeeEntity.getDepartmentId()); + } + + public List getDepartmentAndSubIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + return departmentService.selfAndChildrenIdList(employeeEntity.getDepartmentId()); + } + + /** + * 根据员工id 获取各数据范围最大的可见范围 map + */ + public DataScopeViewTypeEnum getEmployeeDataScopeViewType(DataScopeTypeEnum dataScopeTypeEnum, Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (employeeEntity == null || employeeEntity.getEmployeeId() == null) { + return DataScopeViewTypeEnum.ME; + } + + // 如果是超级管理员 则可查看全部 + if (employeeEntity.getAdministratorFlag()) { + return DataScopeViewTypeEnum.ALL; + } + + List roleIdList = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + //未设置角色 默认本人 + if (CollectionUtils.isEmpty(roleIdList)) { + return DataScopeViewTypeEnum.ME; + } + //未设置角色数据范围 默认本人 + List dataScopeRoleList = roleDataScopeDao.listByRoleIdList(roleIdList); + if (CollectionUtils.isEmpty(dataScopeRoleList)) { + return DataScopeViewTypeEnum.ME; + } + Map> listMap = dataScopeRoleList.stream().collect(Collectors.groupingBy(RoleDataScopeEntity::getDataScopeType)); + List viewLevelList = listMap.getOrDefault(dataScopeTypeEnum.getValue(), Lists.newArrayList()); + if (CollectionUtils.isEmpty(viewLevelList)) { + return DataScopeViewTypeEnum.ME; + } + RoleDataScopeEntity maxLevel = viewLevelList.stream().max(Comparator.comparing(e -> SmartEnumUtil.getEnumByValue(e.getViewType(), DataScopeViewTypeEnum.class).getLevel())).get(); + return SmartEnumUtil.getEnumByValue(maxLevel.getViewType(), DataScopeViewTypeEnum.class); + } + + /** + * 获取本人相关 可查看员工id + */ + private List getMeEmployeeIdList(Long employeeId) { + return Lists.newArrayList(employeeId); + } + + /** + * 获取本部门相关 可查看员工id + */ + private List getDepartmentEmployeeIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + return employeeDao.getEmployeeIdByDepartmentId(employeeEntity.getDepartmentId(), false); + } + + /** + * 获取本部门及下属子部门相关 可查看员工id + */ + private List getDepartmentAndSubEmployeeIdList(Long employeeId) { + List allDepartmentIds = getDepartmentAndSubIdList(employeeId); + return employeeDao.getEmployeeIdByDepartmentIdList(allDepartmentIds, false); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/AbstractDataScopeStrategy.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/AbstractDataScopeStrategy.java new file mode 100644 index 0000000..a18c5cf --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/AbstractDataScopeStrategy.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.module.system.datascope.strategy; + +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; + +import java.util.Map; + +/** + * 数据范围策略 ,使用DataScopeWhereInTypeEnum.CUSTOM_STRATEGY类型,DataScope注解的joinSql属性无用 + */ +public abstract class AbstractDataScopeStrategy { + + /** + * 获取joinsql 字符串 + */ + public abstract String getCondition(DataScopeViewTypeEnum viewTypeEnum, Map paramMap, DataScopeSqlConfig sqlConfigDTO); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java new file mode 100644 index 0000000..8741594 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.module.system.department.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentAddForm; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentUpdateForm; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentTreeVO; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 部门 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_DEPARTMENT) +public class DepartmentController { + + @Resource + private DepartmentService departmentService; + + @Operation(summary = "查询部门树形列表") + @GetMapping("/department/treeList") + public ResponseDTO> departmentTree() { + return departmentService.departmentTree(); + } + + @Operation(summary = "添加部门") + @PostMapping("/department/add") + @SaCheckPermission("system:department:add") + public ResponseDTO addDepartment(@Valid @RequestBody DepartmentAddForm createDTO) { + return departmentService.addDepartment(createDTO); + } + + @Operation(summary = "更新部门") + @PostMapping("/department/update") + @SaCheckPermission("system:department:update") + public ResponseDTO updateDepartment(@Valid @RequestBody DepartmentUpdateForm updateDTO) { + return departmentService.updateDepartment(updateDTO); + } + + @Operation(summary = "删除部门") + @GetMapping("/department/delete/{departmentId}") + @SaCheckPermission("system:department:delete") + public ResponseDTO deleteDepartment(@PathVariable Long departmentId) { + return departmentService.deleteDepartment(departmentId); + } + + @Operation(summary = "查询部门列表") + @GetMapping("/department/listAll") + public ResponseDTO> listAll() { + return ResponseDTO.ok(departmentService.listAll()); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java new file mode 100644 index 0000000..4d8de53 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.system.department.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 部门 + */ +@Mapper +public interface DepartmentDao extends BaseMapper { + + /** + * 根据部门id,查询此部门直接子部门的数量 + * + */ + Integer countSubDepartment(@Param("departmentId") Long departmentId); + + /** + * 获取全部部门列表 + */ + List listAll(); + + DepartmentVO selectDepartmentVO(@Param("departmentId")Long departmentId); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java new file mode 100644 index 0000000..7623acf --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.system.department.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 部门实体类 + */ +@Data +@TableName(value = "t_department") +public class DepartmentEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long departmentId; + + /** + * 部门名称 + */ + private String departmentName; + + /** + * 负责人员工 id + */ + @TableField(updateStrategy = FieldStrategy.NEVER) + private Long managerId; + + /** + * 部门父级id + */ + private Long parentId; + + /** + * 排序 + */ + private Integer sort; + + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java new file mode 100644 index 0000000..8097b4c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.system.department.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 部门 添加表单 + */ +@Data +public class DepartmentAddForm { + + @Schema(description = "部门名称") + @Length(min = 1, max = 50, message = "请输入正确的部门名称(1-50个字符)") + @NotNull(message = "请输入正确的部门名称(1-50个字符)") + private String departmentName; + + @Schema(description = "排序") + @NotNull(message = "排序值") + private Integer sort; + + @Schema(description = "部门负责人id") + private Long managerId; + + @Schema(description = "上级部门id (可选)") + private Long parentId; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java new file mode 100644 index 0000000..9fbcbc0 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.admin.module.system.department.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 部门 更新表单 + */ +@Data +public class DepartmentUpdateForm extends DepartmentAddForm { + + @Schema(description = "部门id") + @NotNull(message = "部门id不能为空") + private Long departmentId; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java new file mode 100644 index 0000000..d24d241 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.system.department.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; + +import java.util.List; + +/** + * 部门 + */ +@Data +public class DepartmentEmployeeTreeVO extends DepartmentVO { + + @Schema(description = "部门员工列表") + private List employees; + + @Schema(description = "子部门") + private List children; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java new file mode 100644 index 0000000..f396cc2 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.system.department.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 部门 + */ +@Data +public class DepartmentTreeVO extends DepartmentVO { + + @Schema(description = "同级上一个元素id") + private Long preId; + + @Schema(description = "同级下一个元素id") + private Long nextId; + + @Schema(description = "子部门") + private List children; + + @Schema(description = "自己和所有递归子部门的id集合") + private List selfAndAllChildrenIdList; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java new file mode 100644 index 0000000..f58d41b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.department.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 部门 + */ +@Data +public class DepartmentVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "部门id") + private Long departmentId; + + @Schema(description = "部门名称") + private String departmentName; + + @Schema(description = "部门负责人姓名") + private String managerName; + + @Schema(description = "部门负责人id") + private Long managerId; + + @Schema(description = "父级部门id") + private Long parentId; + + @Schema(description = "排序") + private Integer sort; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java new file mode 100644 index 0000000..3827c49 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java @@ -0,0 +1,220 @@ +package net.lab1024.sa.admin.module.system.department.manager; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminCacheConst; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentTreeVO; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 部门 缓存相关 + */ +@Slf4j +@Service +public class DepartmentCacheManager { + + @Resource + private DepartmentDao departmentDao; + + private void logClearInfo(String cache) { + log.info("clear " + cache); + } + + @CacheEvict(value = {AdminCacheConst.Department.DEPARTMENT_LIST_CACHE, AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE, AdminCacheConst.Department.DEPARTMENT_TREE_CACHE, AdminCacheConst.Department.DEPARTMENT_PATH_CACHE,}, allEntries = true) + public void clearCache() { + logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE); + } + + + /** + * 部门列表 + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE) + public List getDepartmentList() { + return departmentDao.listAll(); + } + + /** + * 缓存部门树结构 + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_TREE_CACHE) + public List getDepartmentTree() { + List departmentVOList = departmentDao.listAll(); + return this.buildTree(departmentVOList); + } + + /** + * 缓存某个部门的下级id列表 + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE) + public List getDepartmentSelfAndChildren(Long departmentId) { + List departmentVOList = departmentDao.listAll(); + return this.selfAndChildrenIdList(departmentId, departmentVOList); + } + + + /** + * 部门的路径名称 + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE) + public Map getDepartmentPathMap() { + List departmentVOList = departmentDao.listAll(); + Map departmentMap = departmentVOList.stream().collect(Collectors.toMap(DepartmentVO::getDepartmentId, Function.identity())); + + Map pathNameMap = Maps.newHashMap(); + for (DepartmentVO departmentVO : departmentVOList) { + String pathName = this.buildDepartmentPath(departmentVO, departmentMap); + pathNameMap.put(departmentVO.getDepartmentId(), pathName); + } + + return pathNameMap; + } + + /** + * 构建父级考点路径 + */ + private String buildDepartmentPath(DepartmentVO departmentVO, Map departmentMap) { + if (Objects.equals(departmentVO.getParentId(), NumberUtils.LONG_ZERO)) { + return departmentVO.getDepartmentName(); + } + //父节点 + DepartmentVO parentDepartment = departmentMap.get(departmentVO.getParentId()); + if (parentDepartment == null) { + return departmentVO.getDepartmentName(); + } + String pathName = buildDepartmentPath(parentDepartment, departmentMap); + return pathName + "/" + departmentVO.getDepartmentName(); + + } + // ---------------------- 构造树的一些方法 ------------------------------ + + /** + * 构建部门树结构 + */ + public List buildTree(List voList) { + if (CollectionUtils.isEmpty(voList)) { + return Lists.newArrayList(); + } + List rootList = voList.stream().filter(e -> e.getParentId() == null || Objects.equals(e.getParentId(), NumberUtils.LONG_ZERO)).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(rootList)) { + return Lists.newArrayList(); + } + List treeVOList = SmartBeanUtil.copyList(rootList, DepartmentTreeVO.class); + this.recursiveBuildTree(treeVOList, voList); + return treeVOList; + } + + /** + * 构建所有根节点的下级树形结构 + * 返回值为层序遍历结果 + * [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历] + */ + private List recursiveBuildTree(List nodeList, List allDepartmentList) { + int nodeSize = nodeList.size(); + List childIdList = new ArrayList<>(); + for (int i = 0; i < nodeSize; i++) { + int preIndex = i - 1; + int nextIndex = i + 1; + DepartmentTreeVO node = nodeList.get(i); + if (preIndex > -1) { + node.setPreId(nodeList.get(preIndex).getDepartmentId()); + } + if (nextIndex < nodeSize) { + node.setNextId(nodeList.get(nextIndex).getDepartmentId()); + } + + List children = getChildren(node.getDepartmentId(), allDepartmentList); + + List tempChildIdList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(children)) { + node.setChildren(children); + tempChildIdList = this.recursiveBuildTree(children, allDepartmentList); + } + + if (CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) { + node.setSelfAndAllChildrenIdList( + new ArrayList<>() + ); + } + node.getSelfAndAllChildrenIdList().add(node.getDepartmentId()); + + if (CollectionUtils.isNotEmpty(tempChildIdList)) { + node.getSelfAndAllChildrenIdList().addAll(tempChildIdList); + childIdList.addAll(tempChildIdList); + } + + } + + // 保证本层遍历顺序 + for (int i = nodeSize - 1; i >= 0; i--) { + childIdList.add(0, nodeList.get(i).getDepartmentId()); + } + + return childIdList; + } + + + /** + * 获取子元素 + */ + private List getChildren(Long departmentId, List voList) { + List childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(childrenEntityList)) { + return Lists.newArrayList(); + } + return SmartBeanUtil.copyList(childrenEntityList, DepartmentTreeVO.class); + } + + + /** + * 通过部门id,获取当前以及下属部门 + */ + public List selfAndChildrenIdList(Long departmentId, List voList) { + List selfAndChildrenIdList = Lists.newArrayList(); + if (CollectionUtils.isEmpty(voList)) { + return selfAndChildrenIdList; + } + selfAndChildrenIdList.add(departmentId); + List children = this.getChildren(departmentId, voList); + if (CollectionUtils.isEmpty(children)) { + return selfAndChildrenIdList; + } + List childrenIdList = children.stream().map(DepartmentTreeVO::getDepartmentId).collect(Collectors.toList()); + selfAndChildrenIdList.addAll(childrenIdList); + for (Long childId : childrenIdList) { + this.selfAndChildrenRecursion(selfAndChildrenIdList, childId, voList); + } + return selfAndChildrenIdList; + } + + /** + * 递归查询 + */ + public void selfAndChildrenRecursion(List selfAndChildrenIdList, Long departmentId, List voList) { + List children = this.getChildren(departmentId, voList); + if (CollectionUtils.isEmpty(children)) { + return; + } + List childrenIdList = children.stream().map(DepartmentTreeVO::getDepartmentId).collect(Collectors.toList()); + selfAndChildrenIdList.addAll(childrenIdList); + for (Long childId : childrenIdList) { + this.selfAndChildrenRecursion(selfAndChildrenIdList, childId, voList); + } + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java new file mode 100644 index 0000000..9098c96 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java @@ -0,0 +1,150 @@ +package net.lab1024.sa.admin.module.system.department.service; + +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentAddForm; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentUpdateForm; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentTreeVO; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.manager.DepartmentCacheManager; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 部门 service + */ +@Service +public class DepartmentService { + + @Resource + private DepartmentDao departmentDao; + + @Resource + private EmployeeDao employeeDao; + + @Resource + private DepartmentCacheManager departmentCacheManager; + + // ---------------------------- 增加、修改、删除 ---------------------------- + + /** + * 新增添加部门 + */ + + public ResponseDTO addDepartment(DepartmentAddForm departmentAddForm) { + DepartmentEntity departmentEntity = SmartBeanUtil.copy(departmentAddForm, DepartmentEntity.class); + departmentDao.insert(departmentEntity); + this.clearCache(); + return ResponseDTO.ok(); + } + + + /** + * 更新部门信息 + */ + public ResponseDTO updateDepartment(DepartmentUpdateForm updateDTO) { + if (updateDTO.getParentId() == null) { + return ResponseDTO.userErrorParam("父级部门id不能为空"); + } + DepartmentEntity entity = departmentDao.selectById(updateDTO.getDepartmentId()); + if (entity == null) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + DepartmentEntity departmentEntity = SmartBeanUtil.copy(updateDTO, DepartmentEntity.class); + departmentEntity.setSort(updateDTO.getSort()); + departmentDao.updateById(departmentEntity); + this.clearCache(); + return ResponseDTO.ok(); + } + + /** + * 根据id删除部门 + * 1、需要判断当前部门是否有子部门,有子部门则不允许删除 + * 2、需要判断当前部门是否有员工,有员工则不能删除 + */ + public ResponseDTO deleteDepartment(Long departmentId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (null == departmentEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 是否有子级部门 + int subDepartmentNum = departmentDao.countSubDepartment(departmentId); + if (subDepartmentNum > 0) { + return ResponseDTO.userErrorParam("请先删除子级部门"); + } + + // 是否有未删除员工 + int employeeNum = employeeDao.countByDepartmentId(departmentId, Boolean.FALSE); + if (employeeNum > 0) { + return ResponseDTO.userErrorParam("请先删除部门员工"); + } + departmentDao.deleteById(departmentId); + // 清除缓存 + this.clearCache(); + return ResponseDTO.ok(); + } + + /** + * 清除自身以及下级的id列表缓存 + */ + private void clearCache() { + departmentCacheManager.clearCache(); + } + + // ---------------------------- 查询 ---------------------------- + + /** + * 获取部门树形结构 + */ + public ResponseDTO> departmentTree() { + List treeVOList = departmentCacheManager.getDepartmentTree(); + return ResponseDTO.ok(treeVOList); + } + + + /** + * 自身以及所有下级的部门id列表 + */ + public List selfAndChildrenIdList(Long departmentId) { + return departmentCacheManager.getDepartmentSelfAndChildren(departmentId); + } + + + /** + * 获取所有部门 + */ + public List listAll() { + return departmentCacheManager.getDepartmentList(); + } + + + /** + * 获取部门 + */ + public DepartmentVO getDepartmentById(Long departmentId) { + return departmentDao.selectDepartmentVO(departmentId); + } + + /** + * 获取部门路径:/公司/研发部/产品组 + */ + public String getDepartmentPath(Long departmentId) { + return departmentCacheManager.getDepartmentPathMap().get(departmentId); + } + + /** + * 获取部门单个信息 + * @param departmentId + * @return + */ + public DepartmentEntity queryByFirmId(Long departmentId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + return departmentEntity; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java new file mode 100644 index 0000000..905e917 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java @@ -0,0 +1,123 @@ +package net.lab1024.sa.admin.module.system.employee.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.employee.domain.form.*; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiDecrypt; +import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 员工 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_EMPLOYEE) +public class EmployeeController { + + @Resource + private EmployeeService employeeService; + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + @PostMapping("/employee/query") + @Operation(summary = "员工管理查询") + public ResponseDTO> query(@Valid @RequestBody EmployeeQueryForm query) { + return employeeService.queryEmployee(query); + } + + @Operation(summary = "添加员工(返回添加员工的密码)") + @PostMapping("/employee/add") + @SaCheckPermission("system:employee:add") + public ResponseDTO addEmployee(@Valid @RequestBody EmployeeAddForm employeeAddForm) { + return employeeService.addEmployee(employeeAddForm); + } + + @Operation(summary = "更新员工") + @PostMapping("/employee/update") + @SaCheckPermission("system:employee:update") + public ResponseDTO updateEmployee(@Valid @RequestBody EmployeeUpdateForm employeeUpdateForm) { + return employeeService.updateEmployee(employeeUpdateForm); + } + + @Operation(summary = "更新员工个人中心信息") + @PostMapping("/employee/update/center") + public ResponseDTO updateCenter(@Valid @RequestBody EmployeeUpdateCenterForm updateCenterForm) { + updateCenterForm.setEmployeeId(SmartRequestUtil.getRequestUserId()); + return employeeService.updateCenter(updateCenterForm); + } + + @Operation(summary = "更新登录人头像") + @PostMapping("/employee/update/avatar") + public ResponseDTO updateAvatar(@Valid @RequestBody EmployeeUpdateAvatarForm employeeUpdateAvatarForm) { + employeeUpdateAvatarForm.setEmployeeId(SmartRequestUtil.getRequestUserId()); + return employeeService.updateAvatar(employeeUpdateAvatarForm); + } + + @Operation(summary = "更新员工禁用/启用状态") + @GetMapping("/employee/update/disabled/{employeeId}") + @SaCheckPermission("system:employee:disabled") + public ResponseDTO updateDisableFlag(@PathVariable Long employeeId) { + return employeeService.updateDisableFlag(employeeId); + } + + @Operation(summary = "批量删除员工") + @PostMapping("/employee/update/batch/delete") + @SaCheckPermission("system:employee:delete") + public ResponseDTO batchUpdateDeleteFlag(@RequestBody List employeeIdList) { + return employeeService.batchUpdateDeleteFlag(employeeIdList); + } + + @Operation(summary = "批量调整员工部门") + @PostMapping("/employee/update/batch/department") + @SaCheckPermission("system:employee:department:update") + public ResponseDTO batchUpdateDepartment(@Valid @RequestBody EmployeeBatchUpdateDepartmentForm batchUpdateDepartmentForm) { + return employeeService.batchUpdateDepartment(batchUpdateDepartmentForm); + } + + @Operation(summary = "修改密码") + @PostMapping("/employee/update/password") + @ApiDecrypt + public ResponseDTO updatePassword(@Valid @RequestBody EmployeeUpdatePasswordForm updatePasswordForm) { + updatePasswordForm.setEmployeeId(SmartRequestUtil.getRequestUserId()); + return employeeService.updatePassword(SmartRequestUtil.getRequestUser(), updatePasswordForm); + } + + @Operation(summary = "获取密码复杂度") + @GetMapping("/employee/getPasswordComplexityEnabled") + @ApiDecrypt + public ResponseDTO getPasswordComplexityEnabled() { + return ResponseDTO.ok(level3ProtectConfigService.isPasswordComplexityEnabled()); + } + + @Operation(summary = "重置员工密码") + @GetMapping("/employee/update/password/reset/{employeeId}") + @SaCheckPermission("system:employee:password:reset") + public ResponseDTO resetPassword(@PathVariable Long employeeId) { + return employeeService.resetPassword(employeeId); + } + + @Operation(summary = "查询员工-根据部门id") + @GetMapping("/employee/getAllEmployeeByDepartmentId/{departmentId}") + public ResponseDTO> getAllEmployeeByDepartmentId(@PathVariable Long departmentId) { + return employeeService.getAllEmployeeByDepartmentId(departmentId); + } + + @Operation(summary = "查询所有员工") + @GetMapping("/employee/queryAll") + public ResponseDTO> queryAllEmployee(@RequestParam(value = "disabledFlag", required = false) Boolean disabledFlag) { + return employeeService.queryAllEmployee(disabledFlag); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java new file mode 100644 index 0000000..b140533 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java @@ -0,0 +1,105 @@ +package net.lab1024.sa.admin.module.system.employee.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.domain.form.EmployeeQueryForm; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 员工 dao + */ +@Mapper +public interface EmployeeDao extends BaseMapper { + /** + * 查询员工列表 + */ + List queryEmployee(Page page, @Param("queryForm") EmployeeQueryForm queryForm, @Param("departmentIdList") List departmentIdList); + + /** + * 查询员工 + */ + List selectEmployeeByDisabledAndDeleted(@Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 更新单个 + */ + void updateDisableFlag(@Param("employeeId") Long employeeId, @Param("disabledFlag") Boolean disabledFlag); + + /** + * 通过登录名查询 + */ + EmployeeEntity getByLoginName(@Param("loginName") String loginName, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 通过姓名查询 + */ + EmployeeEntity getByActualName(@Param("actualName") String actualName, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 通过手机号查询 + */ + EmployeeEntity getByPhone(@Param("phone") String phone, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 通过邮箱账号查询 + */ + EmployeeEntity getByEmail(@Param("email") String email, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 获取所有员工 + */ + List listAll(); + + /** + * 获取某个部门员工数 + */ + Integer countByDepartmentId(@Param("departmentId") Long departmentId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 获取一批员工 + */ + List getEmployeeByIds(@Param("employeeIds") Collection employeeIds); + + /** + * 查询单个员工信息 + */ + EmployeeVO getEmployeeById(@Param("employeeId") Long employeeId); + + /** + * 获取某个部门的员工 + */ + List selectByDepartmentId(@Param("departmentId") Long departmentId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询某些部门下用户名是xxx的员工 + */ + List selectByActualName(@Param("departmentIdList") List departmentIdList, @Param("actualName") String actualName, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 获取某批部门的员工Id + */ + List getEmployeeIdByDepartmentIdList(@Param("departmentIds") List departmentIds, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 获取所有 + */ + List getEmployeeId(@Param("leaveFlag") Boolean leaveFlag, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 获取某个部门的员工Id + */ + List getEmployeeIdByDepartmentId(@Param("departmentId") Long departmentId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 员工重置密码 + */ + Integer updatePassword(@Param("employeeId") Long employeeId, @Param("password") String password); + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java new file mode 100644 index 0000000..07ce223 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java @@ -0,0 +1,101 @@ +package net.lab1024.sa.admin.module.system.employee.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; + +/** + * 员工 实体表 + */ +@Data +@TableName("t_employee") +public class EmployeeEntity { + + @TableId(type = IdType.AUTO) + private Long employeeId; + + /** + * 唯一id + */ + private String employeeUid; + + + /** + * 登录账号 + */ + private String loginName; + + /** + * 登录密码 + */ + private String loginPwd; + + /** + * 员工名称 + */ + private String actualName; + + /** + * 头像 + */ + private String avatar; + + /** + * 性别 + */ + private Integer gender; + + /** + * 手机号码 + */ + private String phone; + + /** + * 邮箱 + */ + private String email; + + /** + * 部门id + */ + private Long departmentId; + + /** + * 职务级别ID + */ + private Long positionId; + + /** + * 是否为超级管理员: 0 不是,1是 + */ + private Boolean administratorFlag; + + /** + * 是否被禁用 0否1是 + */ + private Boolean disabledFlag; + + /** + * 是否删除0否 1是 + */ + private Boolean deletedFlag; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + + /** + * 执业证号 + */ + private String certificateNumber; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java new file mode 100644 index 0000000..266015c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.GenderEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; +import net.lab1024.sa.base.common.util.SmartVerificationUtil; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import java.util.List; + +/** + * 添加员工 + */ +@Data +public class EmployeeAddForm { + + @Schema(description = "姓名") + @NotNull(message = "姓名不能为空") + @Length(max = 30, message = "姓名最多30字符") + private String actualName; + + @Schema(description = "登录账号") + @NotNull(message = "登录账号不能为空") + @Length(max = 30, message = "登录账号最多30字符") + private String loginName; + + @SchemaEnum(GenderEnum.class) + @CheckEnum(value = GenderEnum.class, message = "性别错误") + private Integer gender; + + @Schema(description = "部门id") + @NotNull(message = "部门id不能为空") + private Long departmentId; + + @Schema(description = "是否启用") + @NotNull(message = "是否被禁用不能为空") + private Boolean disabledFlag; + + @Schema(description = "手机号") + @NotNull(message = "手机号不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String phone; + + @Schema(description = "邮箱账号") + @NotNull(message = "邮箱账号不能为空") + @Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱账号格式不正确") + private String email; + + @Schema(description = "职务级别ID") + private Long positionId; + + @Schema(description = "角色列表") + private List roleIdList; + + @Schema(description = "备注") + @Length(max = 200, message = "备注最多200字符") + private String remark; + + @Schema(description = "职业证号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "职业证号 不能为空") + private String certificateNumber; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java new file mode 100644 index 0000000..4f9f575 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 员工更新部门 + */ +@Data +public class EmployeeBatchUpdateDepartmentForm { + + @Schema(description = "员工id") + @NotEmpty(message = "员工id不能为空") + @Size(max = 99, message = "一次最多调整99个员工") + private List employeeIdList; + + @Schema(description = "部门ID") + @NotNull(message = "部门ID不能为空") + private Long departmentId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java new file mode 100644 index 0000000..6435b12 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 员工列表 + */ +@Data +public class EmployeeQueryForm extends PageParam { + + @Schema(description = "搜索词") + @Length(max = 20, message = "搜索词最多20字符") + private String keyword; + + @Schema(description = "部门id") + private Long departmentId; + + @Schema(description = "是否禁用") + private Boolean disabledFlag; + + @Schema(description = "员工id集合") + @Size(max = 99, message = "最多查询99个员工") + private List employeeIdList; + + @Schema(description = "删除标识", hidden = true) + private Boolean deletedFlag; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateAvatarForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateAvatarForm.java new file mode 100644 index 0000000..1b253cd --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateAvatarForm.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.util.SmartVerificationUtil; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 修改登录人头像 + */ +@Data +public class EmployeeUpdateAvatarForm { + + @Schema(hidden = true) + private Long employeeId; + + @Schema(description = "头像") + @NotBlank(message = "头像不能为空哦") + private String avatar; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateCenterForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateCenterForm.java new file mode 100644 index 0000000..8a1be15 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateCenterForm.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.GenderEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.util.SmartVerificationUtil; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + + +/** + * 更新员工个人中心信息 + */ +@Data +public class EmployeeUpdateCenterForm { + + @Schema(hidden = true) + private Long employeeId; + + @Schema(description = "姓名") + @NotNull(message = "姓名不能为空") + @Length(max = 30, message = "姓名最多30字符") + private String actualName; + + @SchemaEnum(GenderEnum.class) + @CheckEnum(value = GenderEnum.class, message = "性别错误") + private Integer gender; + + @Schema(description = "手机号") + @NotNull(message = "手机号不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String phone; + + @Schema(description = "邮箱账号") + @NotNull(message = "邮箱账号不能为空") + @Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱账号格式不正确") + private String email; + + @Schema(description = "职务级别ID") + private Long positionId; + + @Schema(description = "头像") + private String avatar; + + @Schema(description = "备注") + @Length(max = 200, message = "备注最多200字符") + private String remark; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java new file mode 100644 index 0000000..daa3bdb --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 更新员工 + */ +@Data +public class EmployeeUpdateForm extends EmployeeAddForm { + + @Schema(description = "员工id") + @NotNull(message = "员工id不能为空") + private Long employeeId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java new file mode 100644 index 0000000..5fd43a0 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.util.SmartVerificationUtil; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 修改密码所需参数 + */ +@Data +public class EmployeeUpdatePasswordForm { + + @Schema(hidden = true) + private Long employeeId; + + @Schema(description = "原密码") + @NotBlank(message = "原密码不能为空哦") + private String oldPassword; + + @Schema(description = "新密码") + @NotBlank(message = "新密码不能为空哦") + private String newPassword; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java new file mode 100644 index 0000000..4511eac --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 员工更新角色 + */ +@Data +public class EmployeeUpdateRoleForm { + + @Schema(description = "员工id") + @NotNull(message = "员工id不能为空") + private Long employeeId; + + @Schema(description = "角色ids") + @Size(max = 99, message = "角色最多99") + private List roleIdList; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java new file mode 100644 index 0000000..0908d2c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java @@ -0,0 +1,64 @@ +package net.lab1024.sa.admin.module.system.employee.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.GenderEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 员工信息 + */ +@Data +public class EmployeeVO { + + @Schema(description = "主键id") + private Long employeeId; + + @Schema(description = "登录账号") + private String loginName; + + @SchemaEnum(GenderEnum.class) + private Integer gender; + + @Schema(description = "员工名称") + private String actualName; + + @Schema(description = "手机号码") + private String phone; + + @Schema(description = "部门id") + private Long departmentId; + + @Schema(description = "是否被禁用") + private Boolean disabledFlag; + + @Schema(description = "是否 超级管理员") + private Boolean administratorFlag; + + @Schema(description = "部门名称") + private String departmentName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "角色列表") + private List roleIdList; + + @Schema(description = "角色名称列表") + private List roleNameList; + + @Schema(description = "职务ID") + private Long positionId; + + @Schema(description = "职务名称") + private String positionName; + + @Schema(description = "邮箱") + private String email; + + @Schema(description = "职业证号") + private String certificateNumber; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java new file mode 100644 index 0000000..128a03d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.admin.module.system.employee.manager; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 员工 manager + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-12-29 21:52:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class EmployeeManager extends ServiceImpl { + + @Resource + private EmployeeDao employeeDao; + + @Resource + private RoleEmployeeService roleEmployeeService; + + @Resource + private RoleEmployeeDao roleEmployeeDao; + + /** + * 保存员工 + * + */ + @Transactional(rollbackFor = Throwable.class) + public void saveEmployee(EmployeeEntity employee, List roleIdList) { + // 保存员工 获得id + employeeDao.insert(employee); + + if (CollectionUtils.isNotEmpty(roleIdList)) { + List roleEmployeeList = roleIdList.stream().map(e -> new RoleEmployeeEntity(e, employee.getEmployeeId())).collect(Collectors.toList()); + roleEmployeeService.batchInsert(roleEmployeeList); + } + } + + /** + * 更新员工 + * + */ + @Transactional(rollbackFor = Throwable.class) + public void updateEmployee(EmployeeEntity employee, List roleIdList) { + // 保存员工 获得id + employeeDao.updateById(employee); + + // 若为空,则删除所有角色 + if (CollectionUtils.isEmpty(roleIdList)) { + roleEmployeeDao.deleteByEmployeeId(employee.getEmployeeId()); + return; + } + + List roleEmployeeList = roleIdList.stream().map(e -> new RoleEmployeeEntity(e, employee.getEmployeeId())).collect(Collectors.toList()); + this.updateEmployeeRole(employee.getEmployeeId(), roleEmployeeList); + } + + /** + * 更新员工角色 + */ + @Transactional(rollbackFor = Throwable.class) + public void updateEmployeeRole(Long employeeId, List roleEmployeeList) { + + roleEmployeeDao.deleteByEmployeeId(employeeId); + + if (CollectionUtils.isNotEmpty(roleEmployeeList)) { + roleEmployeeService.batchInsert(roleEmployeeList); + } + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java new file mode 100644 index 0000000..4bb7fb5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java @@ -0,0 +1,456 @@ +package net.lab1024.sa.admin.module.system.employee.service; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.lang.UUID; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.domain.form.*; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.employee.manager.EmployeeManager; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.admin.module.system.position.dao.PositionDao; +import net.lab1024.sa.admin.module.system.position.domain.entity.PositionEntity; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleEmployeeVO; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.securityprotect.service.SecurityPasswordService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 员工 service + */ +@Service +public class EmployeeService { + + @Resource + private EmployeeDao employeeDao; + + @Resource + private DepartmentDao departmentDao; + + @Resource + private EmployeeManager employeeManager; + + @Resource + private RoleEmployeeDao roleEmployeeDao; + + @Resource + private DepartmentService departmentService; + + @Resource + private SecurityPasswordService securityPasswordService; + + @Resource + @Lazy + private LoginService loginService; + + @Resource + private PositionDao positionDao; + + public EmployeeEntity getById(Long employeeId) { + return employeeDao.selectById(employeeId); + } + + + /** + * 查询员工列表 + */ + public ResponseDTO> queryEmployee(EmployeeQueryForm employeeQueryForm) { + employeeQueryForm.setDeletedFlag(false); + Page pageParam = SmartPageUtil.convert2PageQuery(employeeQueryForm); + + List departmentIdList = new ArrayList<>(); + if (employeeQueryForm.getDepartmentId() != null) { + departmentIdList.addAll(departmentService.selfAndChildrenIdList(employeeQueryForm.getDepartmentId())); + } + + List employeeList = employeeDao.queryEmployee(pageParam, employeeQueryForm, departmentIdList); + if (CollectionUtils.isEmpty(employeeList)) { + PageResult pageResult = SmartPageUtil.convert2PageResult(pageParam, employeeList); + return ResponseDTO.ok(pageResult); + } + + // 查询员工角色 + List employeeIdList = employeeList.stream().map(EmployeeVO::getEmployeeId).collect(Collectors.toList()); + List roleEmployeeEntityList = employeeIdList.isEmpty() ? Collections.emptyList() : roleEmployeeDao.selectRoleByEmployeeIdList(employeeIdList); + Map> employeeRoleIdListMap = roleEmployeeEntityList.stream().collect(Collectors.groupingBy(RoleEmployeeVO::getEmployeeId, Collectors.mapping(RoleEmployeeVO::getRoleId, Collectors.toList()))); + Map> employeeRoleNameListMap = roleEmployeeEntityList.stream().collect(Collectors.groupingBy(RoleEmployeeVO::getEmployeeId, Collectors.mapping(RoleEmployeeVO::getRoleName, Collectors.toList()))); + + // 查询员工职位 + List positionIdList = employeeList.stream().map(EmployeeVO::getPositionId).filter(Objects::nonNull).collect(Collectors.toList()); + List positionEntityList = positionIdList.isEmpty() ? Collections.emptyList() : positionDao.selectBatchIds(positionIdList); + Map positionNameMap = positionEntityList.stream().collect(Collectors.toMap(PositionEntity::getPositionId, PositionEntity::getPositionName)); + + employeeList.forEach(e -> { + e.setRoleIdList(employeeRoleIdListMap.getOrDefault(e.getEmployeeId(), Lists.newArrayList())); + e.setRoleNameList(employeeRoleNameListMap.getOrDefault(e.getEmployeeId(), Lists.newArrayList())); + e.setDepartmentName(departmentService.getDepartmentPath(e.getDepartmentId())); + e.setPositionName(positionNameMap.get(e.getPositionId())); + }); + PageResult pageResult = SmartPageUtil.convert2PageResult(pageParam, employeeList); + return ResponseDTO.ok(pageResult); + } + + /** + * 新增员工 + */ + public synchronized ResponseDTO addEmployee(EmployeeAddForm employeeAddForm) { + // 校验登录名是否重复 + EmployeeEntity employeeEntity = employeeDao.getByLoginName(employeeAddForm.getLoginName(), null); + if (null != employeeEntity) { + return ResponseDTO.userErrorParam("登录名重复"); + } + // 校验电话是否存在 + employeeEntity = employeeDao.getByPhone(employeeAddForm.getPhone(), null); + if (null != employeeEntity) { + return ResponseDTO.userErrorParam("手机号已存在"); + } + // 部门是否存在 + Long departmentId = employeeAddForm.getDepartmentId(); + DepartmentEntity department = departmentDao.selectById(departmentId); + if (department == null) { + return ResponseDTO.userErrorParam("部门不存在"); + } + + EmployeeEntity entity = SmartBeanUtil.copy(employeeAddForm, EmployeeEntity.class); + // 员工uid + String employeeUid = UUID.randomUUID(true).toString(true); + entity.setEmployeeUid(employeeUid); + + // 设置密码 随机密码 + String randomPassword = securityPasswordService.randomPassword(); + String generateSaltPassword = this.generateSaltPassword(randomPassword, employeeUid); + entity.setLoginPwd(SecurityPasswordService.getEncryptPwd(generateSaltPassword)); + + // 保存数据 + entity.setDeletedFlag(Boolean.FALSE); + employeeManager.saveEmployee(entity, employeeAddForm.getRoleIdList()); + + return ResponseDTO.ok(randomPassword); + } + + /** + * 更新员工 + */ + public synchronized ResponseDTO updateEmployee(EmployeeUpdateForm employeeUpdateForm) { + + Long employeeId = employeeUpdateForm.getEmployeeId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 部门是否存在 + Long departmentId = employeeUpdateForm.getDepartmentId(); + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.userErrorParam("部门不存在"); + } + + // 检查唯一性 + ResponseDTO checkResponse = checkUniqueness(employeeId, employeeUpdateForm.getLoginName(), employeeUpdateForm.getPhone(), employeeUpdateForm.getEmail()); + if (!checkResponse.getOk()) { + return checkResponse; + } + + EmployeeEntity entity = SmartBeanUtil.copy(employeeUpdateForm, EmployeeEntity.class); + // 不更新密码 + entity.setLoginPwd(null); + + // 更新数据 + employeeManager.updateEmployee(entity, employeeUpdateForm.getRoleIdList()); + + // 清除员工缓存 + loginService.clearLoginEmployeeCache(employeeId); + + return ResponseDTO.ok(); + } + + /** + * 更新员工个人中心信息 + */ + public ResponseDTO updateCenter(EmployeeUpdateCenterForm updateCenterForm) { + + Long employeeId = updateCenterForm.getEmployeeId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 检查唯一性 登录账号不能修改则不需要检查 + ResponseDTO checkResponse = checkUniqueness(employeeId, "", updateCenterForm.getPhone(), updateCenterForm.getEmail()); + if (!checkResponse.getOk()) { + return checkResponse; + } + + EmployeeEntity employee = SmartBeanUtil.copy(updateCenterForm, EmployeeEntity.class); + // 不更新密码 + employee.setLoginPwd(null); + + // 更新数据 + employeeDao.updateById(employee); + + // 清除员工缓存 + loginService.clearLoginEmployeeCache(employeeId); + + return ResponseDTO.ok(); + } + + /** + * 检查唯一性 + */ + private ResponseDTO checkUniqueness(Long employeeId, String loginName, String phone, String email) { + EmployeeEntity existEntity = employeeDao.getByLoginName(loginName, null); + if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { + return ResponseDTO.userErrorParam("登录名重复"); + } + + existEntity = employeeDao.getByPhone(phone, null); + if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { + return ResponseDTO.userErrorParam("手机号已存在"); + } + + existEntity = employeeDao.getByEmail(email, null); + if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { + return ResponseDTO.userErrorParam("邮箱账号已存在"); + } + + return ResponseDTO.ok(); + } + + /** + * 更新登录人头像 + */ + public ResponseDTO updateAvatar(EmployeeUpdateAvatarForm employeeUpdateAvatarForm) { + Long employeeId = employeeUpdateAvatarForm.getEmployeeId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (employeeEntity == null) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 更新头像 + EmployeeEntity updateEntity = new EmployeeEntity(); + updateEntity.setEmployeeId(employeeId); + updateEntity.setAvatar(employeeUpdateAvatarForm.getAvatar()); + employeeDao.updateById(updateEntity); + + // 清除员工缓存 + loginService.clearLoginEmployeeCache(employeeId); + return ResponseDTO.ok(); + } + + /** + * 更新禁用/启用状态 + */ + public ResponseDTO updateDisableFlag(Long employeeId) { + if (null == employeeId) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + employeeDao.updateDisableFlag(employeeId, !employeeEntity.getDisabledFlag()); + + if (employeeEntity.getDisabledFlag()) { + // 强制退出登录 + StpUtil.logout(UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StringConst.COLON + employeeId); + } + + return ResponseDTO.ok(); + } + + /** + * 批量删除员工 + */ + public ResponseDTO batchUpdateDeleteFlag(List employeeIdList) { + if (CollectionUtils.isEmpty(employeeIdList)) { + return ResponseDTO.ok(); + } + List employeeEntityList = employeeManager.listByIds(employeeIdList); + if (CollectionUtils.isEmpty(employeeEntityList)) { + return ResponseDTO.ok(); + } + // 更新删除 + List deleteList = employeeIdList.stream().map(e -> { + EmployeeEntity updateEmployee = new EmployeeEntity(); + updateEmployee.setEmployeeId(e); + updateEmployee.setDeletedFlag(true); + return updateEmployee; + }).collect(Collectors.toList()); + employeeManager.updateBatchById(deleteList); + + for (Long employeeId : employeeIdList) { + // 强制退出登录 + StpUtil.logout(UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StringConst.COLON + employeeId); + } + return ResponseDTO.ok(); + } + + + /** + * 批量更新部门 + */ + public ResponseDTO batchUpdateDepartment(EmployeeBatchUpdateDepartmentForm batchUpdateDepartmentForm) { + List employeeIdList = batchUpdateDepartmentForm.getEmployeeIdList(); + List employeeEntityList = employeeDao.selectBatchIds(employeeIdList); + if (employeeIdList.size() != employeeEntityList.size()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 更新 + List updateList = employeeIdList.stream().map(e -> { + EmployeeEntity updateEmployee = new EmployeeEntity(); + updateEmployee.setEmployeeId(e); + updateEmployee.setDepartmentId(batchUpdateDepartmentForm.getDepartmentId()); + return updateEmployee; + }).collect(Collectors.toList()); + employeeManager.updateBatchById(updateList); + + return ResponseDTO.ok(); + } + + + /** + * 更新密码 + */ + @Transactional(rollbackFor = Throwable.class) + public ResponseDTO updatePassword(RequestUser requestUser, EmployeeUpdatePasswordForm updatePasswordForm) { + Long employeeId = updatePasswordForm.getEmployeeId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (employeeEntity == null) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 校验原始密码 + if (!SecurityPasswordService.matchesPwd(this.generateSaltPassword(updatePasswordForm.getOldPassword(), employeeEntity.getEmployeeUid()), employeeEntity.getLoginPwd())) { + return ResponseDTO.userErrorParam("原密码有误,请重新输入"); + } + + // 新旧密码相同 + if (Objects.equals(updatePasswordForm.getOldPassword(), updatePasswordForm.getNewPassword())) { + return ResponseDTO.userErrorParam("新密码与原始密码相同,请重新输入"); + } + + // 校验密码复杂度 + ResponseDTO validatePassComplexity = securityPasswordService.validatePasswordComplexity(updatePasswordForm.getNewPassword()); + if (!validatePassComplexity.getOk()) { + return validatePassComplexity; + } + + // 根据三级等保规则,校验密码是否重复 + ResponseDTO passwordRepeatTimes = securityPasswordService.validatePasswordRepeatTimes(requestUser, this.generateSaltPassword(updatePasswordForm.getNewPassword(), employeeEntity.getEmployeeUid())); + if (!passwordRepeatTimes.getOk()) { + return ResponseDTO.error(passwordRepeatTimes); + } + + // 更新密码 + String newEncryptPassword = SecurityPasswordService.getEncryptPwd(this.generateSaltPassword(updatePasswordForm.getNewPassword(), employeeEntity.getEmployeeUid())); + EmployeeEntity updateEntity = new EmployeeEntity(); + updateEntity.setEmployeeId(employeeId); + updateEntity.setLoginPwd(newEncryptPassword); + employeeDao.updateById(updateEntity); + + // 保存修改密码密码记录 + securityPasswordService.saveUserChangePasswordLog(requestUser, newEncryptPassword, employeeEntity.getLoginPwd()); + + return ResponseDTO.ok(); + } + + /** + * 获取某个部门的员工信息 + */ + public ResponseDTO> getAllEmployeeByDepartmentId(Long departmentId) { + List employeeEntityList = employeeDao.selectByDepartmentId(departmentId, Boolean.FALSE); + + if (CollectionUtils.isEmpty(employeeEntityList)) { + return ResponseDTO.ok(Collections.emptyList()); + } + + DepartmentVO department = departmentService.getDepartmentById(departmentId); + + List voList = employeeEntityList.stream().map(e -> { + EmployeeVO employeeVO = SmartBeanUtil.copy(e, EmployeeVO.class); + if (department != null) { + employeeVO.setDepartmentName(department.getDepartmentName()); + } + return employeeVO; + }).collect(Collectors.toList()); + return ResponseDTO.ok(voList); + } + + + /** + * 重置密码 + */ + public ResponseDTO resetPassword(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (employeeEntity == null) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + String password = securityPasswordService.randomPassword(); + String saltPassword = this.generateSaltPassword(password, employeeEntity.getEmployeeUid()); + employeeDao.updatePassword(employeeId, SecurityPasswordService.getEncryptPwd(saltPassword)); + return ResponseDTO.ok(password); + } + + + /** + * 查询全部员工 + */ + public ResponseDTO> queryAllEmployee(Boolean disabledFlag) { + List employeeList = employeeDao.selectEmployeeByDisabledAndDeleted(disabledFlag, Boolean.FALSE); + return ResponseDTO.ok(employeeList); + } + + /** + * 根据登录名获取员工 + */ + public EmployeeEntity getByLoginName(String loginName) { + return employeeDao.getByLoginName(loginName, false); + } + + /** + * 生成加盐密码 + * 格式为:[password]_[uid大写]_[uid小写] + */ + public String generateSaltPassword(String password, String employeeUid) { + return password + StringConst.UNDERLINE + + employeeUid.toUpperCase() + + StringConst.UNDERLINE + + employeeUid.toLowerCase(); + } + + /** + * 查询单个员工信息 + */ + public EmployeeEntity queryById(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + return employeeEntity; + } + + public List getByDepartmentId(Long departmentId) { + return employeeDao.selectList(new LambdaQueryWrapper().eq(EmployeeEntity::getDepartmentId, departmentId)); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java new file mode 100644 index 0000000..7a1ad11 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java @@ -0,0 +1,84 @@ +package net.lab1024.sa.admin.module.system.login.controller; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.extra.servlet.ServletUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.login.domain.LoginForm; +import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.admin.util.AdminRequestUtil; +import net.lab1024.sa.base.common.annoation.NoNeedLogin; +import net.lab1024.sa.base.common.constant.RequestHeaderConst; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.captcha.domain.CaptchaVO; +import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * 员工登录 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_LOGIN) +public class LoginController { + + @Resource + private LoginService loginService; + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + @NoNeedLogin + @PostMapping("/login") + @Operation(summary = "登录") + public ResponseDTO login(@Valid @RequestBody LoginForm loginForm, HttpServletRequest request) { + String ip = ServletUtil.getClientIP(request); + String userAgent = ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT); + return loginService.login(loginForm, ip, userAgent); + } + + @GetMapping("/login/getLoginInfo") + @Operation(summary = "获取登录结果信息") + public ResponseDTO getLoginInfo() { + String tokenValue = StpUtil.getTokenValue(); + LoginResultVO loginResult = loginService.getLoginResult(AdminRequestUtil.getRequestUser(), tokenValue); + loginResult.setToken(tokenValue); + return ResponseDTO.ok(loginResult); + } + + @Operation(summary = "退出登录") + @GetMapping("/login/logout") + public ResponseDTO logout() { + return loginService.logout(SmartRequestUtil.getRequestUser()); + } + + @Operation(summary = "获取验证码") + @GetMapping("/login/getCaptcha") + @NoNeedLogin + public ResponseDTO getCaptcha() { + return loginService.getCaptcha(); + } + + @NoNeedLogin + @GetMapping("/login/sendEmailCode/{loginName}") + @Operation(summary = "获取邮箱登录验证码") + public ResponseDTO sendEmailCode(@PathVariable String loginName) { + return loginService.sendEmailCode(loginName); + } + + + @NoNeedLogin + @GetMapping("/login/getTwoFactorLoginFlag") + @Operation(summary = "获取双因子登录标识") + public ResponseDTO getTwoFactorLoginFlag() { + // 双因子登录 + boolean twoFactorLoginEnabled = level3ProtectConfigService.isTwoFactorLoginEnabled(); + return ResponseDTO.ok(twoFactorLoginEnabled); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java new file mode 100644 index 0000000..5f6a0e6 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.system.login.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.base.constant.LoginDeviceEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 员工登录 + */ +@Data +public class LoginForm extends CaptchaForm { + + @Schema(description = "登录账号") + @NotBlank(message = "登录账号不能为空") + @Length(max = 30, message = "登录账号最多30字符") + private String loginName; + + @Schema(description = "密码") + @NotBlank(message = "密码不能为空") + private String password; + + @SchemaEnum(desc = "登录终端", value = LoginDeviceEnum.class) + @CheckEnum(value = LoginDeviceEnum.class, required = true, message = "此终端不允许登录") + private Integer loginDevice; + + @Schema(description = "邮箱验证码") + private String emailCode; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginResultVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginResultVO.java new file mode 100644 index 0000000..5710b0b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginResultVO.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.admin.module.system.login.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.minidev.json.annotate.JsonIgnore; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 登录结果信息 + */ +@Data +public class LoginResultVO extends RequestEmployee { + + @Schema(description = "token") + private String token; + + @Schema(description = "菜单列表") + private List menuList; + + @Schema(description = "是否需要修改密码") + private Boolean needUpdatePwdFlag; + + @Schema(description = "上次登录ip") + private String lastLoginIp; + + @Schema(description = "上次登录ip地区") + private String lastLoginIpRegion; + + @Schema(description = "上次登录user-agent") + private String lastLoginUserAgent; + + @Schema(description = "上次登录时间") + private LocalDateTime lastLoginTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/RequestEmployee.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/RequestEmployee.java new file mode 100644 index 0000000..dea1ff5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/RequestEmployee.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.admin.module.system.login.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.enumeration.GenderEnum; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.io.Serializable; + +/** + * 请求员工登录信息 + */ +@Data +public class RequestEmployee implements RequestUser, Serializable { + + @Schema(description = "员工id") + private Long employeeId; + + @SchemaEnum(UserTypeEnum.class) + private UserTypeEnum userType; + + @Schema(description = "登录账号") + private String loginName; + + @Schema(description = "员工名称") + private String actualName; + + @Schema(description = "头像") + private String avatar; + + @SchemaEnum(GenderEnum.class) + private Integer gender; + + @Schema(description = "手机号码") + private String phone; + + @Schema(description = "部门id") + private Long departmentId; + + @Schema(description = "部门名称") + private String departmentName; + + @Schema(description = "职务级别ID") + private Long positionId; + + @Schema(description = "邮箱") + private String email; + + @Schema(description = "是否禁用") + private Boolean disabledFlag; + + @Schema(description = "是否为超管") + private Boolean administratorFlag; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "请求ip") + private String ip; + + @Schema(description = "请求user-agent") + private String userAgent; + + @Schema(description = "执业证号") + private String licenseNumber; + + @Override + public Long getUserId() { + return employeeId; + } + + @Override + public String getUserName() { + return actualName; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/manager/LoginManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/manager/LoginManager.java new file mode 100644 index 0000000..2c5ded3 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/manager/LoginManager.java @@ -0,0 +1,167 @@ +package net.lab1024.sa.admin.module.system.login.manager; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminCacheConst; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; +import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.UserPermission; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.module.support.file.service.IFileStorageService; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 登录Manager + */ +@Slf4j +@Service +public class LoginManager { + + @Resource + private DepartmentService departmentService; + + @Resource + private IFileStorageService fileStorageService; + + @Resource + private EmployeeService employeeService; + + @Resource + private RoleEmployeeService roleEmployeeService; + + @Resource + private RoleMenuService roleMenuService; + + + /** + * 获取请求用户信息 + */ + @Cacheable(AdminCacheConst.Login.REQUEST_EMPLOYEE) + public RequestEmployee getRequestEmployee(Long requestEmployeeId ) { + if (requestEmployeeId == null) { + return null; + } + // 员工基本信息 + EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId); + if (employeeEntity == null) { + return null; + } + + return this.loadLoginInfo(employeeEntity); + } + + /** + * 获取登录的用户信息 + */ + @CachePut(value = AdminCacheConst.Login.REQUEST_EMPLOYEE, key = "#employeeEntity.employeeId") + public RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) { + // 基础信息 + RequestEmployee requestEmployee = SmartBeanUtil.copy(employeeEntity, RequestEmployee.class); + requestEmployee.setUserType(UserTypeEnum.ADMIN_EMPLOYEE); + + // 部门信息 + DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId()); + requestEmployee.setDepartmentName(null == department ? StringConst.EMPTY : department.getDepartmentName()); + + // 头像信息 + String avatar = employeeEntity.getAvatar(); + if (StringUtils.isNotBlank(avatar)) { + ResponseDTO getFileUrl = fileStorageService.getFileUrl(avatar); + if (BooleanUtils.isTrue(getFileUrl.getOk())) { + requestEmployee.setAvatar(getFileUrl.getData()); + } + } + return requestEmployee; + } + + + /** + * 获取用户的权限(包含 角色列表、权限列表) + */ + @Cacheable(AdminCacheConst.Login.USER_PERMISSION) + public UserPermission getUserPermission(Long employeeId) { + if(null == employeeId){ + return null; + } + + return this.loadUserPermission(employeeId); + } + + /** + * 获取用户的权限(包含 角色列表、权限列表) + */ + @CachePut(AdminCacheConst.Login.USER_PERMISSION) + public UserPermission loadUserPermission(Long employeeId) { + UserPermission userPermission = new UserPermission(); + userPermission.setPermissionList(new ArrayList<>()); + userPermission.setRoleList(new ArrayList<>()); + + // 角色列表 + List roleList = roleEmployeeService.getRoleIdList(employeeId); + userPermission.getRoleList().addAll(roleList.stream().map(RoleVO::getRoleCode).collect(Collectors.toSet())); + + // 前端菜单和功能点清单 + EmployeeEntity employeeEntity = employeeService.getById(employeeId); + + List menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), employeeEntity.getAdministratorFlag()); + + // 权限列表 + HashSet permissionSet = new HashSet<>(); + for (MenuVO menu : menuAndPointsList) { + if (menu.getPermsType() == null) { + continue; + } + + String perms = menu.getApiPerms(); + if (StringUtils.isEmpty(perms)) { + continue; + } + //接口权限 + String[] split = perms.split(","); + permissionSet.addAll(Arrays.asList(split)); + } + userPermission.getPermissionList().addAll(permissionSet); + + return userPermission; + } + + + /** + * 清除用户权限 + */ + @CacheEvict(value = AdminCacheConst.Login.USER_PERMISSION) + public void clearUserPermission(Long employeeId) { + + } + + /** + * 清除用户登录信息 + */ + @CacheEvict(value = AdminCacheConst.Login.REQUEST_EMPLOYEE) + public void clearUserLoginInfo(Long employeeId) { + + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java new file mode 100644 index 0000000..0b29bec --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java @@ -0,0 +1,478 @@ +package net.lab1024.sa.admin.module.system.login.service; + +import cn.dev33.satoken.stp.StpInterface; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.lang.UUID; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.extra.servlet.ServletUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.admin.module.system.login.domain.LoginForm; +import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO; +import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee; +import net.lab1024.sa.admin.module.system.login.manager.LoginManager; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; +import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.constant.RequestHeaderConst; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.UserPermission; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartIpUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.constant.LoginDeviceEnum; +import net.lab1024.sa.base.constant.RedisKeyConst; +import net.lab1024.sa.base.module.support.apiencrypt.service.ApiEncryptService; +import net.lab1024.sa.base.module.support.captcha.CaptchaService; +import net.lab1024.sa.base.module.support.captcha.domain.CaptchaVO; +import net.lab1024.sa.base.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.base.module.support.config.ConfigService; +import net.lab1024.sa.base.module.support.file.service.IFileStorageService; +import net.lab1024.sa.base.module.support.loginlog.LoginLogResultEnum; +import net.lab1024.sa.base.module.support.loginlog.LoginLogService; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogEntity; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogVO; +import net.lab1024.sa.base.module.support.mail.MailService; +import net.lab1024.sa.base.module.support.mail.constant.MailTemplateCodeEnum; +import net.lab1024.sa.base.module.support.redis.RedisService; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailEntity; +import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService; +import net.lab1024.sa.base.module.support.securityprotect.service.SecurityLoginService; +import net.lab1024.sa.base.module.support.securityprotect.service.SecurityPasswordService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 登录 + */ +@Slf4j +@Service +public class LoginService implements StpInterface { + + /** + * 万能密码的 sa token loginId 前缀 + */ + private static final String SUPER_PASSWORD_LOGIN_ID_PREFIX = "S"; + + @Resource + private EmployeeService employeeService; + + @Resource + private CaptchaService captchaService; + + @Resource + private ConfigService configService; + + @Resource + private LoginLogService loginLogService; + + @Resource + private RoleEmployeeService roleEmployeeService; + + @Resource + private RoleMenuService roleMenuService; + + @Resource + private SecurityLoginService securityLoginService; + + @Resource + private SecurityPasswordService protectPasswordService; + + @Resource + private ApiEncryptService apiEncryptService; + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + @Resource + private MailService mailService; + + @Resource + private RedisService redisService; + + @Resource + private LoginManager loginManager; + + /** + * 获取验证码 + */ + public ResponseDTO getCaptcha() { + return ResponseDTO.ok(captchaService.generateCaptcha()); + } + + /** + * 员工登录 + * + * @return 返回用户登录信息 + */ + public ResponseDTO login(LoginForm loginForm, String ip, String userAgent) { + + LoginDeviceEnum loginDeviceEnum = SmartEnumUtil.getEnumByValue(loginForm.getLoginDevice(), LoginDeviceEnum.class); + if (loginDeviceEnum == null) { + return ResponseDTO.userErrorParam("登录设备暂不支持!"); + } + + // 校验 图形验证码 + ResponseDTO checkCaptcha = captchaService.checkCaptcha(loginForm); + if (!checkCaptcha.getOk()) { + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, checkCaptcha.getMsg()); + } + + // 验证登录名 + EmployeeEntity employeeEntity = employeeService.getByLoginName(loginForm.getLoginName()); + if (null == employeeEntity) { + return ResponseDTO.userErrorParam("登录名或密码错误!"); + } + + // 验证账号状态 + if (employeeEntity.getDeletedFlag()) { + saveLoginLog(employeeEntity, ip, userAgent, "账号已删除", LoginLogResultEnum.LOGIN_FAIL, loginDeviceEnum); + return ResponseDTO.userErrorParam("您的账号已被删除,请联系工作人员!"); + } + + if (employeeEntity.getDisabledFlag()) { + saveLoginLog(employeeEntity, ip, userAgent, "账号已禁用", LoginLogResultEnum.LOGIN_FAIL, loginDeviceEnum); + return ResponseDTO.userErrorParam("您的账号已被禁用,请联系工作人员!"); + } + + // 解密前端加密的密码 + String requestPassword = apiEncryptService.decrypt(loginForm.getPassword()); + + // 验证密码 是否为万能密码 + String superPassword = configService.getConfigValue(ConfigKeyEnum.SUPER_PASSWORD); + boolean superPasswordFlag = superPassword.equals(requestPassword); + + // 校验双因子登录 + ResponseDTO validateEmailCode = validateEmailCode(loginForm, employeeEntity, superPasswordFlag); + if (!validateEmailCode.getOk()) { + return ResponseDTO.error(validateEmailCode); + } + + // 万能密码特殊操作 + if (superPasswordFlag) { + + // 对于万能密码:受限制sa token 要求loginId唯一,万能密码只能插入一段uuid + String saTokenLoginId = SUPER_PASSWORD_LOGIN_ID_PREFIX + StringConst.COLON + UUID.randomUUID().toString().replace("-", "") + StringConst.COLON + employeeEntity.getEmployeeId(); + // 万能密码登录只能登录30分钟 + StpUtil.login(saTokenLoginId, 1800); + + } else { + + // 按照等保登录要求,进行登录失败次数校验 + ResponseDTO loginFailEntityResponseDTO = securityLoginService.checkLogin(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE); + if (!loginFailEntityResponseDTO.getOk()) { + return ResponseDTO.error(loginFailEntityResponseDTO); + } + + // 密码错误 + if (!SecurityPasswordService.matchesPwd(employeeService.generateSaltPassword(requestPassword, employeeEntity.getEmployeeUid()), employeeEntity.getLoginPwd())) { + // 记录登录失败 + saveLoginLog(employeeEntity, ip, userAgent, "密码错误", LoginLogResultEnum.LOGIN_FAIL, loginDeviceEnum); + // 记录等级保护次数 + String msg = securityLoginService.recordLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, employeeEntity.getLoginName(), loginFailEntityResponseDTO.getData()); + return msg == null ? ResponseDTO.userErrorParam("登录名或密码错误!") : ResponseDTO.error(UserErrorCode.LOGIN_FAIL_WILL_LOCK, msg); + } + + String saTokenLoginId = UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StringConst.COLON + employeeEntity.getEmployeeId(); + + // 登录 + StpUtil.login(saTokenLoginId, String.valueOf(loginDeviceEnum.getDesc())); + + // 移除邮箱验证码 + deleteEmailCode(employeeEntity.getEmployeeId()); + } + + // 获取员工信息 + RequestEmployee requestEmployee = loginManager.loadLoginInfo(employeeEntity); + + // 移除登录失败 + securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE); + + // 获取登录结果信息 + String token = StpUtil.getTokenValue(); + LoginResultVO loginResultVO = getLoginResult(requestEmployee, token); + + //保存登录记录 + saveLoginLog(employeeEntity, ip, userAgent, superPasswordFlag ? "万能密码登录" : StringConst.EMPTY, LoginLogResultEnum.LOGIN_SUCCESS, loginDeviceEnum); + + // 设置 token + loginResultVO.setToken(token); + + // 更新用户权限 + loginManager.loadUserPermission(employeeEntity.getEmployeeId()); + + return ResponseDTO.ok(loginResultVO); + } + + + /** + * 获取登录结果信息 + */ + public LoginResultVO getLoginResult(RequestEmployee requestEmployee, String token) { + + // 基础信息 + LoginResultVO loginResultVO = SmartBeanUtil.copy(requestEmployee, LoginResultVO.class); + + // 前端菜单和功能点清单 + List roleList = roleEmployeeService.getRoleIdList(requestEmployee.getEmployeeId()); + List menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), requestEmployee.getAdministratorFlag()); + loginResultVO.setMenuList(menuAndPointsList); + + // 上次登录信息 + LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, LoginLogResultEnum.LOGIN_SUCCESS); + if (loginLogVO != null) { + loginResultVO.setLastLoginIp(loginLogVO.getLoginIp()); + loginResultVO.setLastLoginIpRegion(loginLogVO.getLoginIpRegion()); + loginResultVO.setLastLoginTime(loginLogVO.getCreateTime()); + loginResultVO.setLastLoginUserAgent(loginLogVO.getUserAgent()); + } + + // 是否需要强制修改密码 + boolean needChangePasswordFlag = protectPasswordService.checkNeedChangePassword(requestEmployee.getUserType().getValue(), requestEmployee.getUserId()); + loginResultVO.setNeedUpdatePwdFlag(needChangePasswordFlag); + + // 万能密码登录,则不需要设置强制修改密码 + String loginIdByToken = (String) StpUtil.getLoginIdByToken(token); + if (loginIdByToken != null && loginIdByToken.startsWith(SUPER_PASSWORD_LOGIN_ID_PREFIX)) { + loginResultVO.setNeedUpdatePwdFlag(false); + } + + //查询执业证号 + loginResultVO.setLicenseNumber(employeeService.getById(requestEmployee.getUserId()).getCertificateNumber()); + return loginResultVO; + } + + + /** + * 根据登录token 获取员请求工信息 + */ + public RequestEmployee getLoginEmployee(String loginId, HttpServletRequest request) { + if (loginId == null) { + return null; + } + + Long requestEmployeeId = getEmployeeIdByLoginId(loginId); + if (requestEmployeeId == null) { + return null; + } + + RequestEmployee requestEmployee = loginManager.getRequestEmployee(requestEmployeeId); + + // 更新请求ip和user agent + requestEmployee.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT)); + requestEmployee.setIp(ServletUtil.getClientIP(request)); + + return requestEmployee; + } + + /** + * 根据 loginId 获取 员工id + */ + Long getEmployeeIdByLoginId(String loginId) { + + if (loginId == null) { + return null; + } + + try { + // 如果是 万能密码 登录的用户 + String employeeIdStr = null; + if (loginId.startsWith(SUPER_PASSWORD_LOGIN_ID_PREFIX)) { + employeeIdStr = loginId.split(StringConst.COLON)[2]; + } else { + employeeIdStr = loginId.substring(2); + } + + return Long.parseLong(employeeIdStr); + } catch (Exception e) { + log.error("loginId parse error , loginId : {}", loginId, e); + return null; + } + } + + + /** + * 退出登录 + */ + public ResponseDTO logout(RequestUser requestUser) { + + // sa token 登出 + StpUtil.logout(); + + // 清除用户登录信息缓存和权限信息 + this.clearLoginEmployeeCache(requestUser.getUserId()); + + //保存登出日志 + LoginLogEntity loginEntity = LoginLogEntity.builder() + .userId(requestUser.getUserId()) + .userType(requestUser.getUserType().getValue()) + .userName(requestUser.getUserName()) + .userAgent(requestUser.getUserAgent()) + .loginIp(requestUser.getIp()) + .loginIpRegion(SmartIpUtil.getRegion(requestUser.getIp())) + .loginResult(LoginLogResultEnum.LOGIN_OUT.getValue()) + .createTime(LocalDateTime.now()) + .build(); + loginLogService.log(loginEntity); + + return ResponseDTO.ok(); + } + + /** + * 保存登录日志 + */ + private void saveLoginLog(EmployeeEntity employeeEntity, String ip, String userAgent, String remark, LoginLogResultEnum result, LoginDeviceEnum loginDeviceEnum) { + LoginLogEntity loginEntity = LoginLogEntity.builder() + .userId(employeeEntity.getEmployeeId()) + .userType(UserTypeEnum.ADMIN_EMPLOYEE.getValue()) + .userName(employeeEntity.getActualName()) + .userAgent(userAgent) + .loginIp(ip) + .loginIpRegion(SmartIpUtil.getRegion(ip)) + .remark(remark) + .loginDevice(loginDeviceEnum.getDesc()) + .loginResult(result.getValue()) + .createTime(LocalDateTime.now()) + .build(); + loginLogService.log(loginEntity); + } + + + @Override + public List getPermissionList(Object loginId, String loginType) { + Long employeeId = this.getEmployeeIdByLoginId((String) loginId); + if (employeeId == null) { + return Collections.emptyList(); + } + + UserPermission userPermission = loginManager.getUserPermission(employeeId); + return userPermission.getPermissionList(); + } + + @Override + public List getRoleList(Object loginId, String loginType) { + Long employeeId = this.getEmployeeIdByLoginId((String) loginId); + if (employeeId == null) { + return Collections.emptyList(); + } + + UserPermission userPermission = loginManager.getUserPermission(employeeId); + return userPermission.getRoleList(); + } + + + /** + * 发送 邮箱 验证码 + */ + public ResponseDTO sendEmailCode(String loginName) { + + // 开启双因子登录 + if (!level3ProtectConfigService.isTwoFactorLoginEnabled()) { + return ResponseDTO.userErrorParam("无需使用邮箱验证码"); + } + + // 验证登录名 + EmployeeEntity employeeEntity = employeeService.getByLoginName(loginName); + if (null == employeeEntity) { + return ResponseDTO.ok(); + } + + // 验证账号状态 + if (employeeEntity.getDeletedFlag()) { + return ResponseDTO.userErrorParam("您的账号已被删除,请联系工作人员!"); + } + + if (employeeEntity.getDisabledFlag()) { + return ResponseDTO.userErrorParam("您的账号已被禁用,请联系工作人员!"); + } + + String mail = employeeEntity.getEmail(); + if (SmartStringUtil.isBlank(mail)) { + return ResponseDTO.userErrorParam("您暂未配置邮箱地址,请联系管理员配置邮箱"); + } + + // 校验验证码发送时间,60秒内不能重复发生 + String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeEntity.getEmployeeId()); + String emailCode = redisService.get(redisVerificationCodeKey); + long sendCodeTimeMills = -1; + if (!SmartStringUtil.isEmpty(emailCode)) { + sendCodeTimeMills = NumberUtil.parseLong(emailCode.split(StringConst.UNDERLINE)[1]); + } + + if (System.currentTimeMillis() - sendCodeTimeMills < 60 * 1000) { + return ResponseDTO.userErrorParam("邮箱验证码已发送,一分钟内请勿重复发送"); + } + + //生成验证码 + long currentTimeMillis = System.currentTimeMillis(); + String verificationCode = RandomUtil.randomNumbers(4); + redisService.set(redisVerificationCodeKey, verificationCode + StringConst.UNDERLINE + currentTimeMillis, 300); + + // 发送邮件验证码 + HashMap mailParams = new HashMap<>(); + mailParams.put("code", verificationCode); + return mailService.sendMail(MailTemplateCodeEnum.LOGIN_VERIFICATION_CODE, mailParams, Collections.singletonList(employeeEntity.getEmail())); + } + + + /** + * 校验邮箱验证码 + */ + private ResponseDTO validateEmailCode(LoginForm loginForm, EmployeeEntity employeeEntity, boolean superPasswordFlag) { + // 万能密码则不校验 + if (superPasswordFlag) { + return ResponseDTO.ok(); + } + + // 未开启双因子登录 + if (!level3ProtectConfigService.isTwoFactorLoginEnabled()) { + return ResponseDTO.ok(); + } + + if (SmartStringUtil.isEmpty(loginForm.getEmailCode())) { + return ResponseDTO.userErrorParam("请输入邮箱验证码"); + } + + // 校验验证码 + String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeEntity.getEmployeeId()); + String emailCode = redisService.get(redisVerificationCodeKey); + if (SmartStringUtil.isEmpty(emailCode)) { + return ResponseDTO.userErrorParam("邮箱验证码已失效,请重新发送"); + } + + if (!emailCode.split(StringConst.UNDERLINE)[0].equals(loginForm.getEmailCode().trim())) { + return ResponseDTO.userErrorParam("邮箱验证码错误,请重新填写"); + } + + return ResponseDTO.ok(); + } + + /** + * 移除邮箱验证码 + */ + private void deleteEmailCode(Long employeeId) { + String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeId); + redisService.delete(redisVerificationCodeKey); + } + + public void clearLoginEmployeeCache(Long employeeId) { + loginManager.clearUserPermission(employeeId); + loginManager.clearUserLoginInfo(employeeId); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java new file mode 100644 index 0000000..724820b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.system.menu.constant; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 权限类型 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum MenuPermsTypeEnum implements BaseEnum { + /** + * sa-token + */ + SA_TOKEN(1, "Sa-Token模式"), + + ; + + private final Integer value; + + private final String desc; + + + MenuPermsTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java new file mode 100644 index 0000000..c447443 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.system.menu.constant; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 菜单类型枚举 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum MenuTypeEnum implements BaseEnum { + /** + * 目录 + */ + CATALOG(1, "目录"), + /** + * 菜单 + */ + MENU(2, "菜单"), + /** + * 功能点 + */ + POINTS(3, "功能点"); + + private final Integer value; + + private final String desc; + + + MenuTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java new file mode 100644 index 0000000..4c83c24 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java @@ -0,0 +1,84 @@ +package net.lab1024.sa.admin.module.system.menu.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuAddForm; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuUpdateForm; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuTreeVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.menu.service.MenuService; +import net.lab1024.sa.base.common.domain.RequestUrlVO; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_MENU) +public class MenuController { + + @Resource + private MenuService menuService; + + @Operation(summary = "添加菜单 @author 卓大") + @PostMapping("/menu/add") + @SaCheckPermission("system:menu:add") + public ResponseDTO addMenu(@RequestBody @Valid MenuAddForm menuAddForm) { + menuAddForm.setCreateUserId(SmartRequestUtil.getRequestUserId()); + return menuService.addMenu(menuAddForm); + } + + @Operation(summary = "更新菜单 @author 卓大") + @PostMapping("/menu/update") + @SaCheckPermission("system:menu:update") + public ResponseDTO updateMenu(@RequestBody @Valid MenuUpdateForm menuUpdateForm) { + menuUpdateForm.setUpdateUserId(SmartRequestUtil.getRequestUserId()); + return menuService.updateMenu(menuUpdateForm); + } + + @Operation(summary = "批量删除菜单 @author 卓大") + @GetMapping("/menu/batchDelete") + @SaCheckPermission("system:menu:batchDelete") + public ResponseDTO batchDeleteMenu(@RequestParam("menuIdList") List menuIdList) { + return menuService.batchDeleteMenu(menuIdList, SmartRequestUtil.getRequestUserId()); + } + + @Operation(summary = "查询菜单列表 @author 卓大") + @GetMapping("/menu/query") + public ResponseDTO> queryMenuList() { + return ResponseDTO.ok(menuService.queryMenuList(null)); + } + + @Operation(summary = "查询菜单详情 @author 卓大") + @GetMapping("/menu/detail/{menuId}") + public ResponseDTO getMenuDetail(@PathVariable Long menuId) { + return menuService.getMenuDetail(menuId); + } + + @Operation(summary = "查询菜单树 @author 卓大") + @GetMapping("/menu/tree") + public ResponseDTO> queryMenuTree(@RequestParam("onlyMenu") Boolean onlyMenu) { + return menuService.queryMenuTree(onlyMenu); + } + + @Operation(summary = "获取所有请求路径 @author 卓大") + @GetMapping("/menu/auth/url") + public ResponseDTO> getAuthUrl() { + return menuService.getAuthUrl(); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java new file mode 100644 index 0000000..e2cd1b5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java @@ -0,0 +1,96 @@ +package net.lab1024.sa.admin.module.system.menu.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; + +import java.util.List; + +/** + * 菜单 dao + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface MenuDao extends BaseMapper { + + /** + * 根据名称查询同一级下的菜单 + * + * @param menuName 菜单名 + * @param parentId 父级id + * @param deletedFlag 是否删除 + */ + MenuEntity getByMenuName(@Param("menuName") String menuName, @Param("parentId") Long parentId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据前端权限字符串查询菜单 + * + * @param webPerms 前端权限字符串 + * @param deletedFlag 是否删除 + */ + MenuEntity getByWebPerms(@Param("webPerms") String webPerms, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据菜单ID删除菜单(逻辑删除) + * + * @param menuIdList 菜单id集合 + * @param updateUserId 操作人id + * @param deletedFlag 是否删除 + */ + void deleteByMenuIdList(@Param("menuIdList") List menuIdList, @Param("updateUserId") Long updateUserId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询菜单列表 + * + * @param deletedFlag 是否删除 + * @param disabledFlag 是否禁用 + * @param menuTypeList 菜单类型集合 + */ + List queryMenuList(@Param("deletedFlag") Boolean deletedFlag, @Param("disabledFlag") Boolean disabledFlag, @Param("menuTypeList") List menuTypeList); + + + /** + * 根据菜单ID 查询功能点列表 + * + * @param menuId 菜单id + * @param menuType 菜单类型 + * @param deletedFlag 删除标记 + */ + List getPointListByMenuId(@Param("menuId") Long menuId, @Param("menuType") Integer menuType, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据员工ID查询菜单列表 + * + * @param deletedFlag 是否删除 + * @param disabledFlag 禁用标识 + * @param employeeId 员工id + */ + List queryMenuByEmployeeId(@Param("deletedFlag") Boolean deletedFlag, + @Param("disabledFlag") Boolean disabledFlag, + @Param("employeeId") Long employeeId); + + /** + * 根据菜单类型查询 + * + * @param menuType 菜单类型 + * @param deletedFlag 删除 + * @param disabledFlag 禁用 + */ + List queryMenuByType(@Param("menuType") Integer menuType, + @Param("deletedFlag") Boolean deletedFlag, + @Param("disabledFlag") Boolean disabledFlag); + + /** + * 查询孩子id + * + */ + List selectMenuIdByParentIdList(@Param("menuIdList") List menuIdList); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java new file mode 100644 index 0000000..a25f60a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java @@ -0,0 +1,136 @@ +package net.lab1024.sa.admin.module.system.menu.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; + +import java.time.LocalDateTime; + +/** + * 菜单 表 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName(value = "t_menu") +public class MenuEntity { + + /** + * 菜单ID + */ + @TableId(type = IdType.AUTO) + private Long menuId; + + /** + * 菜单名称 + */ + private String menuName; + + /** + * 类型 + * + * @see MenuTypeEnum + */ + private Integer menuType; + + /** + * 父菜单ID + */ + private Long parentId; + + /** + * 显示顺序 + */ + private Integer sort; + + /** + * 路由地址 + */ + private String path; + + /** + * 组件路径 + */ + private String component; + + /** + * 是否为外链 + */ + private Boolean frameFlag; + + /** + * 外链地址 + */ + private String frameUrl; + + /** + * 是否缓存 + */ + private Boolean cacheFlag; + + /** + * 显示状态 + */ + private Boolean visibleFlag; + + /** + * 禁用状态 + */ + private Boolean disabledFlag; + + /** + * 后端权限字符串 + */ + private String apiPerms; + + /** + * 权限类型 + */ + private Integer permsType; + + /** + * 前端权限字符串 + */ + private String webPerms; + + /** + * 菜单图标 + */ + private String icon; + + /** + * 功能点关联菜单ID + */ + private Long contextMenuId; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 创建人 + */ + private Long createUserId; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 更新人 + */ + private Long updateUserId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java new file mode 100644 index 0000000..e80584b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 菜单 添加表单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuAddForm extends MenuBaseForm { + + @Schema(hidden = true) + private Long createUserId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java new file mode 100644 index 0000000..ba388eb --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java @@ -0,0 +1,82 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.constant.MenuPermsTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 菜单基础 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuBaseForm { + + @Schema(description = "菜单名称") + @NotBlank(message = "菜单名称不能为空") + @Length(max = 30, message = "菜单名称最多30个字符") + private String menuName; + + @SchemaEnum(value = MenuTypeEnum.class, desc = "类型") + @CheckEnum(value = MenuTypeEnum.class, message = "类型错误") + private Integer menuType; + + @Schema(description = "父菜单ID 无上级可传0") + @NotNull(message = "父菜单ID不能为空") + private Long parentId; + + @Schema(description = "显示顺序") + private Integer sort; + + @Schema(description = "路由地址") + private String path; + + @Schema(description = "组件路径") + private String component; + + @Schema(description = "是否为外链") + @NotNull(message = "是否为外链不能为空") + private Boolean frameFlag; + + @Schema(description = "外链地址") + private String frameUrl; + + @Schema(description = "是否缓存") + @NotNull(message = "是否缓存不能为空") + private Boolean cacheFlag; + + @Schema(description = "显示状态") + @NotNull(message = "显示状态不能为空") + private Boolean visibleFlag; + + @Schema(description = "禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @SchemaEnum(value = MenuPermsTypeEnum.class, desc = "权限类型 ") + @CheckEnum(value = MenuPermsTypeEnum.class, message = "权限类型") + private Integer permsType; + + @Schema(description = "前端权限字符串") + private String webPerms; + + @Schema(description = "后端端权限字符串") + private String apiPerms; + + @Schema(description = "菜单图标") + private String icon; + + @Schema(description = "功能点关联菜单ID") + private Long contextMenuId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java new file mode 100644 index 0000000..6a8dcb3 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 菜单功能点操作Form + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuPointsOperateForm { + + @Schema(description = "菜单ID") + private Long menuId; + + @Schema(description = "功能点名称") + @NotBlank(message = "功能点不能为空") + @Length(max = 30, message = "功能点最多30个字符") + private String menuName; + + @Schema(description = "禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @Schema(description = "后端接口权限集合") + private List apiPermsList; + + @Schema(description = "权限字符串") + private String webPerms; + + @Schema(description = "功能点关联菜单ID") + private Long contextMenuId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java new file mode 100644 index 0000000..9fefb25 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 菜单 更新Form + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuUpdateForm extends MenuBaseForm { + + @Schema(description = "菜单ID") + @NotNull(message = "菜单ID不能为空") + private Long menuId; + + @Schema(hidden = true) + private Long updateUserId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java new file mode 100644 index 0000000..8257d12 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.admin.module.system.menu.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 简易的菜单VO + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuSimpleTreeVO { + + @Schema(description = "菜单ID") + private Long menuId; + + @Schema(description = "菜单名称") + private String menuName; + + @Schema(description = "功能点关联菜单ID") + private Long contextMenuId; + + @Schema(description = "父级菜单ID") + private Long parentId; + + @Schema(description = "菜单类型") + private Integer menuType; + + @Schema(description = "子菜单") + private List children; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java new file mode 100644 index 0000000..5b69813 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.module.system.menu.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuTreeVO extends MenuVO{ + + @Schema(description = "菜单子集") + private List children; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java new file mode 100644 index 0000000..e809bda --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.menu.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuBaseForm; + +import java.time.LocalDateTime; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class MenuVO extends MenuBaseForm { + + @Schema(description = "菜单ID") + private Long menuId; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "创建人") + private Long createUserId; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "更新人") + private Long updateUserId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java new file mode 100644 index 0000000..3dbf61f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java @@ -0,0 +1,237 @@ +package net.lab1024.sa.admin.module.system.menu.service; + +import cn.hutool.core.collection.CollectionUtil; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; +import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuAddForm; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuBaseForm; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuUpdateForm; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuTreeVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.base.common.code.SystemErrorCode; +import net.lab1024.sa.base.common.domain.RequestUrlVO; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-08 22:15:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class MenuService { + + @Resource + private MenuDao menuDao; + + @Resource + private List authUrl; + + /** + * 添加菜单 + * + */ + public synchronized ResponseDTO addMenu(MenuAddForm menuAddForm) { + // 校验菜单名称 + if (this.validateMenuName(menuAddForm)) { + return ResponseDTO.userErrorParam("菜单名称已存在"); + } + // 校验前端权限字符串 + if (this.validateWebPerms(menuAddForm)) { + return ResponseDTO.userErrorParam("前端权限字符串已存在"); + } + MenuEntity menuEntity = SmartBeanUtil.copy(menuAddForm, MenuEntity.class); + menuDao.insert(menuEntity); + return ResponseDTO.ok(); + } + + /** + * 更新菜单 + * + */ + public synchronized ResponseDTO updateMenu(MenuUpdateForm menuUpdateForm) { + //校验菜单是否存在 + MenuEntity selectMenu = menuDao.selectById(menuUpdateForm.getMenuId()); + if (selectMenu == null) { + return ResponseDTO.userErrorParam("菜单不存在"); + } + if (selectMenu.getDeletedFlag()) { + return ResponseDTO.userErrorParam("菜单已被删除"); + } + //校验菜单名称 + if (this.validateMenuName(menuUpdateForm)) { + return ResponseDTO.userErrorParam("菜单名称已存在"); + } + // 校验前端权限字符串 + if (this.validateWebPerms(menuUpdateForm)) { + return ResponseDTO.userErrorParam("前端权限字符串已存在"); + } + if (menuUpdateForm.getMenuId().equals(menuUpdateForm.getParentId())) { + return ResponseDTO.userErrorParam("上级菜单不能为自己"); + } + MenuEntity menuEntity = SmartBeanUtil.copy(menuUpdateForm, MenuEntity.class); + menuDao.updateById(menuEntity); + return ResponseDTO.ok(); + } + + + /** + * 批量删除菜单 + * + */ + public synchronized ResponseDTO batchDeleteMenu(List menuIdList, Long employeeId) { + if (CollectionUtils.isEmpty(menuIdList)) { + return ResponseDTO.userErrorParam("所选菜单不能为空"); + } + menuDao.deleteByMenuIdList(menuIdList, employeeId, Boolean.TRUE); + //孩子节点也需要删除 + this.recursiveDeleteChildren(menuIdList, employeeId); + return ResponseDTO.ok(); + } + + private void recursiveDeleteChildren(List menuIdList, Long employeeId) { + List childrenMenuIdList = menuDao.selectMenuIdByParentIdList(menuIdList); + if (CollectionUtil.isEmpty(childrenMenuIdList)) { + return; + } + menuDao.deleteByMenuIdList(childrenMenuIdList, employeeId, Boolean.TRUE); + recursiveDeleteChildren(childrenMenuIdList, employeeId); + } + + /** + * 校验菜单名称 + * + */ + public Boolean validateMenuName(T menuDTO) { + MenuEntity menu = menuDao.getByMenuName(menuDTO.getMenuName(), menuDTO.getParentId(), Boolean.FALSE); + if (menuDTO instanceof MenuAddForm) { + return menu != null; + } + if (menuDTO instanceof MenuUpdateForm) { + Long menuId = ((MenuUpdateForm) menuDTO).getMenuId(); + return menu != null && menu.getMenuId().longValue() != menuId.longValue(); + } + return true; + } + + /** + * 校验前端权限字符串 + * + * @return true 重复 false 未重复 + */ + public Boolean validateWebPerms(T menuDTO) { + if(SmartStringUtil.isEmpty(menuDTO.getWebPerms())){ + return false; + } + + MenuEntity menu = menuDao.getByWebPerms(menuDTO.getWebPerms(), Boolean.FALSE); + if (menuDTO instanceof MenuAddForm) { + return menu != null; + } + if (menuDTO instanceof MenuUpdateForm) { + Long menuId = ((MenuUpdateForm) menuDTO).getMenuId(); + return menu != null && menu.getMenuId().longValue() != menuId.longValue(); + } + return true; + } + + /** + * 查询菜单列表 + * + */ + public List queryMenuList(Boolean disabledFlag) { + List menuVOList = menuDao.queryMenuList(Boolean.FALSE, disabledFlag, null); + //根据ParentId进行分组 + Map> parentMap = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId, Collectors.toList())); + return this.filterNoParentMenu(parentMap, NumberUtils.LONG_ZERO); + } + + /** + * 过滤没有上级菜单的菜单列表 + * + */ + private List filterNoParentMenu(Map> parentMap, Long parentId) { + // 获取本级菜单树List + List res = parentMap.getOrDefault(parentId, Lists.newArrayList()); + List childMenu = Lists.newArrayList(); + // 循环遍历下级菜单 + res.forEach(e -> { + List menuList = this.filterNoParentMenu(parentMap, e.getMenuId()); + childMenu.addAll(menuList); + }); + res.addAll(childMenu); + return res; + } + + /** + * 查询菜单树 + * + * @param onlyMenu 不查询功能点 + */ + public ResponseDTO> queryMenuTree(Boolean onlyMenu) { + List menuTypeList = Lists.newArrayList(); + if (onlyMenu) { + menuTypeList = Lists.newArrayList(MenuTypeEnum.CATALOG.getValue(), MenuTypeEnum.MENU.getValue()); + } + List menuVOList = menuDao.queryMenuList(Boolean.FALSE, null, menuTypeList); + //根据ParentId进行分组 + Map> parentMap = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId, Collectors.toList())); + List menuTreeVOList = this.buildMenuTree(parentMap, NumberUtils.LONG_ZERO); + return ResponseDTO.ok(menuTreeVOList); + } + + /** + * 构建菜单树 + * + */ + List buildMenuTree(Map> parentMap, Long parentId) { + // 获取本级菜单树List + List res = parentMap.getOrDefault(parentId, Lists.newArrayList()).stream() + .map(e -> SmartBeanUtil.copy(e, MenuTreeVO.class)).collect(Collectors.toList()); + // 循环遍历下级菜单 + res.forEach(e -> { + e.setChildren(this.buildMenuTree(parentMap, e.getMenuId())); + }); + return res; + } + + /** + * 查询菜单详情 + * + */ + public ResponseDTO getMenuDetail(Long menuId) { + //校验菜单是否存在 + MenuEntity selectMenu = menuDao.selectById(menuId); + if (selectMenu == null) { + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "菜单不存在"); + } + if (selectMenu.getDeletedFlag()) { + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "菜单已被删除"); + } + MenuVO menuVO = SmartBeanUtil.copy(selectMenu, MenuVO.class); + return ResponseDTO.ok(menuVO); + } + + /** + * 获取系统所有请求路径 + */ + public ResponseDTO> getAuthUrl() { + return ResponseDTO.ok(authUrl); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/message/AdminMessageController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/message/AdminMessageController.java new file mode 100644 index 0000000..09ea2e5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/message/AdminMessageController.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.system.message; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.base.module.support.message.domain.MessageQueryForm; +import net.lab1024.sa.base.module.support.message.domain.MessageSendForm; +import net.lab1024.sa.base.module.support.message.domain.MessageVO; +import net.lab1024.sa.base.module.support.message.service.MessageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 后管 消息路由 + * + * @author: 卓大 + * @date: 2025/04/09 20:55 + */ +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_MESSAGE) +@RestController +public class AdminMessageController { + + @Autowired + private MessageService messageService; + + @Operation(summary = "通知消息-新建 @author 卓大") + @PostMapping("/message/sendMessages") + @SaCheckPermission("system:message:send") + public ResponseDTO sendMessages(@RequestBody @Valid ValidateList messageList) { + messageService.sendMessage(messageList); + return ResponseDTO.ok(); + } + + @Operation(summary = "通知消息-分页查询 @author 卓大") + @PostMapping("/message/query") + @SaCheckPermission("system:message:query") + public ResponseDTO> query(@RequestBody @Valid MessageQueryForm queryForm) { + return ResponseDTO.ok(messageService.query(queryForm)); + } + + @Operation(summary = "通知消息-删除 @author 卓大") + @GetMapping("/message/delete/{messageId}") + @SaCheckPermission("system:message:delete") + public ResponseDTO delete(@PathVariable Long messageId) { + return messageService.delete(messageId); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/controller/PositionController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/controller/PositionController.java new file mode 100644 index 0000000..5a6c83b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/controller/PositionController.java @@ -0,0 +1,75 @@ +package net.lab1024.sa.admin.module.system.position.controller; + +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionAddForm; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionQueryForm; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionUpdateForm; +import net.lab1024.sa.admin.module.system.position.domain.vo.PositionVO; +import net.lab1024.sa.admin.module.system.position.service.PositionService; +import net.lab1024.sa.base.common.domain.ValidateList; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 职务表 Controller + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_POSITION) +public class PositionController { + + @Resource + private PositionService positionService; + + @Operation(summary = "分页查询 @author kaiyun") + @PostMapping("/position/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid PositionQueryForm queryForm) { + return ResponseDTO.ok(positionService.queryPage(queryForm)); + } + + @Operation(summary = "添加 @author kaiyun") + @PostMapping("/position/add") + public ResponseDTO add(@RequestBody @Valid PositionAddForm addForm) { + return positionService.add(addForm); + } + + @Operation(summary = "更新 @author kaiyun") + @PostMapping("/position/update") + public ResponseDTO update(@RequestBody @Valid PositionUpdateForm updateForm) { + return positionService.update(updateForm); + } + + @Operation(summary = "批量删除 @author kaiyun") + @PostMapping("/position/batchDelete") + public ResponseDTO batchDelete(@RequestBody ValidateList idList) { + return positionService.batchDelete(idList); + } + + @Operation(summary = "单个删除 @author kaiyun") + @GetMapping("/position/delete/{positionId}") + public ResponseDTO batchDelete(@PathVariable Long positionId) { + return positionService.delete(positionId); + } + + + @Operation(summary = "不分页查询 @author kaiyun") + @GetMapping("/position/queryList") + public ResponseDTO> queryList() { + return ResponseDTO.ok(positionService.queryList()); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/dao/PositionDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/dao/PositionDao.java new file mode 100644 index 0000000..5fd307a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/dao/PositionDao.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.system.position.dao; + +import java.util.List; +import net.lab1024.sa.admin.module.system.position.domain.entity.PositionEntity; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionQueryForm; +import net.lab1024.sa.admin.module.system.position.domain.vo.PositionVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 职务表 Dao + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Mapper +public interface PositionDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") PositionQueryForm queryForm); + + + /** + * 查询 + * @param deletedFlag + * @return + */ + List queryList(@Param("deletedFlag") Boolean deletedFlag); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/entity/PositionEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/entity/PositionEntity.java new file mode 100644 index 0000000..dd511bc --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/entity/PositionEntity.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.admin.module.system.position.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.time.LocalDateTime; + +import lombok.Data; + +/** + * 职务表 实体类 + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Data +@TableName("t_position") +public class PositionEntity { + + /** + * 职务ID + */ + @TableId(type = IdType.AUTO) + private Long positionId; + + /** + * 职务名称 + */ + private String positionName; + + /** + * 职级 + */ + private String positionLevel; + + /** + * 排序 + */ + private Integer sort; + + /** + * 备注 + */ + private String remark; + + private Boolean deletedFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionAddForm.java new file mode 100644 index 0000000..f7d4d30 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionAddForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.system.position.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +/** + * 职务表 新建表单 + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Data +public class PositionAddForm { + + @Schema(description = "职务名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "职务名称 不能为空") + private String positionName; + + @Schema(description = "职级") + private String positionLevel; + + @Schema(description = "排序") + @NotNull(message = "排序不能为空") + private Integer sort; + + @Schema(description = "备注") + private String remark; + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionQueryForm.java new file mode 100644 index 0000000..c6b7155 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionQueryForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.system.position.domain.form; + +import net.lab1024.sa.base.common.domain.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 职务表 分页查询表单 + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Data +public class PositionQueryForm extends PageParam{ + + @Schema(description = "关键字查询") + private String keywords; + + @Schema(hidden = true) + private Boolean deletedFlag; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionUpdateForm.java new file mode 100644 index 0000000..298334c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/form/PositionUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.position.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +import lombok.Data; + +/** + * 职务表 更新表单 + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Data +public class PositionUpdateForm extends PositionAddForm { + + @Schema(description = "职务ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "职务ID 不能为空") + private Long positionId; + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/vo/PositionVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/vo/PositionVO.java new file mode 100644 index 0000000..05783ac --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/domain/vo/PositionVO.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.system.position.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 职务表 列表VO + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Data +public class PositionVO { + + + @Schema(description = "职务ID") + private Long positionId; + + @Schema(description = "职务名称") + private String positionName; + + @Schema(description = "职级") + private String positionLevel; + + @Schema(description = "排序") + private Integer sort; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/manager/PositionManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/manager/PositionManager.java new file mode 100644 index 0000000..1759de8 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/manager/PositionManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.position.manager; + +import net.lab1024.sa.admin.module.system.position.dao.PositionDao; +import net.lab1024.sa.admin.module.system.position.domain.entity.PositionEntity; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 职务表 Manager + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ +@Service +public class PositionManager extends ServiceImpl { + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/service/PositionService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/service/PositionService.java new file mode 100644 index 0000000..1d13296 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/position/service/PositionService.java @@ -0,0 +1,105 @@ +package net.lab1024.sa.admin.module.system.position.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.system.position.dao.PositionDao; +import net.lab1024.sa.admin.module.system.position.domain.entity.PositionEntity; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionAddForm; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionQueryForm; +import net.lab1024.sa.admin.module.system.position.domain.form.PositionUpdateForm; +import net.lab1024.sa.admin.module.system.position.domain.vo.PositionVO; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 职务表 Service + * + * @Author kaiyun + * @Date 2024-06-23 23:31:38 + * @Copyright 1024创新实验室 + */ + +@Service +public class PositionService { + + @Resource + private PositionDao positionDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(PositionQueryForm queryForm) { + queryForm.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = positionDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + /** + * 添加 + */ + public ResponseDTO add(PositionAddForm addForm) { + PositionEntity positionEntity = SmartBeanUtil.copy(addForm, PositionEntity.class); + positionDao.insert(positionEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + * @param updateForm + * @return + */ + public ResponseDTO update(PositionUpdateForm updateForm) { + PositionEntity positionEntity = SmartBeanUtil.copy(updateForm, PositionEntity.class); + positionDao.updateById(positionEntity); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + * + * @param idList + * @return + */ + public ResponseDTO batchDelete(List idList) { + if (CollectionUtils.isEmpty(idList)){ + return ResponseDTO.ok(); + } + + positionDao.deleteBatchIds(idList); + return ResponseDTO.ok(); + } + + /** + * 单个删除 + */ + public ResponseDTO delete(Long positionId) { + if (null == positionId){ + return ResponseDTO.ok(); + } + + positionDao.deleteById(positionId); + return ResponseDTO.ok(); + } + + /** + * 分页查询 + * + * @return + */ + public List queryList() { + List list = positionDao.queryList(Boolean.FALSE); + return list; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java new file mode 100644 index 0000000..edd9d0e --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleAddForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.admin.module.system.role.service.RoleService; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 角色 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-12-14 19:40:28 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_ROLE) +public class RoleController { + + @Resource + private RoleService roleService; + + @Operation(summary = "添加角色 @author 卓大") + @PostMapping("/role/add") + @SaCheckPermission("system:role:add") + public ResponseDTO addRole(@Valid @RequestBody RoleAddForm roleAddForm) { + return roleService.addRole(roleAddForm); + } + + @Operation(summary = "删除角色 @author 卓大") + @GetMapping("/role/delete/{roleId}") + @SaCheckPermission("system:role:delete") + public ResponseDTO deleteRole(@PathVariable Long roleId) { + return roleService.deleteRole(roleId); + } + + @Operation(summary = "更新角色 @author 卓大") + @PostMapping("/role/update") + @SaCheckPermission("system:role:update") + public ResponseDTO updateRole(@Valid @RequestBody RoleUpdateForm roleUpdateDTO) { + return roleService.updateRole(roleUpdateDTO); + } + + @Operation(summary = "获取角色数据 @author 卓大") + @GetMapping("/role/get/{roleId}") + public ResponseDTO getRole(@PathVariable("roleId") Long roleId) { + return roleService.getRoleById(roleId); + } + + @Operation(summary = "获取所有角色 @author 卓大") + @GetMapping("/role/getAll") + public ResponseDTO> getAllRole() { + return roleService.getAllRole(); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java new file mode 100644 index 0000000..0d05943 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleDataScopeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleDataScopeVO; +import net.lab1024.sa.admin.module.system.role.service.RoleDataScopeService; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 角色的数据权限配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 22:09:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_ROLE_DATA_SCOPE) +public class RoleDataScopeController { + + @Resource + private RoleDataScopeService roleDataScopeService; + + @Operation(summary = "获取某角色所设置的数据范围 @author 卓大") + @GetMapping("/role/dataScope/getRoleDataScopeList/{roleId}") + public ResponseDTO> dataScopeListByRole(@PathVariable Long roleId) { + return roleDataScopeService.getRoleDataScopeList(roleId); + } + + @Operation(summary = "批量设置某角色数据范围 @author 卓大") + @PostMapping("/role/dataScope/updateRoleDataScopeList") + @SaCheckPermission("system:role:dataScope:update") + public ResponseDTO updateRoleDataScopeList(@RequestBody @Valid RoleDataScopeUpdateForm roleDataScopeUpdateForm) { + return roleDataScopeService.updateRoleDataScopeList(roleDataScopeUpdateForm); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java new file mode 100644 index 0000000..61a61f2 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleSelectedVO; +import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 角色的员工 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 22:09:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_ROLE_EMPLOYEE) +public class RoleEmployeeController { + + @Resource + private RoleEmployeeService roleEmployeeService; + + @Operation(summary = "查询某个角色下的员工列表 @author 卓大") + @PostMapping("/role/employee/queryEmployee") + public ResponseDTO> queryEmployee(@Valid @RequestBody RoleEmployeeQueryForm roleEmployeeQueryForm) { + return roleEmployeeService.queryEmployee(roleEmployeeQueryForm); + } + + @Operation(summary = "获取某个角色下的所有员工列表(无分页) @author 卓大") + @GetMapping("/role/employee/getAllEmployeeByRoleId/{roleId}") + public ResponseDTO> listAllEmployeeRoleId(@PathVariable Long roleId) { + return ResponseDTO.ok(roleEmployeeService.getAllEmployeeByRoleId(roleId)); + } + + @Operation(summary = "从角色成员列表中移除员工 @author 卓大") + @GetMapping("/role/employee/removeEmployee") + @SaCheckPermission("system:role:employee:delete") + public ResponseDTO removeEmployee(Long employeeId, Long roleId) { + return roleEmployeeService.removeRoleEmployee(employeeId, roleId); + } + + @Operation(summary = "从角色成员列表中批量移除员工 @author 卓大") + @PostMapping("/role/employee/batchRemoveRoleEmployee") + @SaCheckPermission("system:role:employee:batch:delete") + public ResponseDTO batchRemoveEmployee(@Valid @RequestBody RoleEmployeeUpdateForm updateForm) { + return roleEmployeeService.batchRemoveRoleEmployee(updateForm); + } + + @Operation(summary = "角色成员列表中批量添加员工 @author 卓大") + @PostMapping("/role/employee/batchAddRoleEmployee") + @SaCheckPermission("system:role:employee:add") + public ResponseDTO addEmployeeList(@Valid @RequestBody RoleEmployeeUpdateForm addForm) { + return roleEmployeeService.batchAddRoleEmployee(addForm); + } + + @Operation(summary = "获取员工所有选中的角色和所有角色 @author 卓大") + @GetMapping("/role/employee/getRoles/{employeeId}") + public ResponseDTO> getRoleByEmployeeId(@PathVariable Long employeeId) { + return ResponseDTO.ok(roleEmployeeService.getRoleInfoListByEmployeeId(employeeId)); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java new file mode 100644 index 0000000..4dfaa35 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleMenuUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleMenuTreeVO; +import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 角色的菜单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = AdminSwaggerTagConst.System.SYSTEM_ROLE_MENU) +public class RoleMenuController { + + @Resource + private RoleMenuService roleMenuService; + + @Operation(summary = "更新角色权限 @author 卓大") + @PostMapping("/role/menu/updateRoleMenu") + @SaCheckPermission("system:role:menu:update") + public ResponseDTO updateRoleMenu(@Valid @RequestBody RoleMenuUpdateForm updateDTO) { + return roleMenuService.updateRoleMenu(updateDTO); + } + + @Operation(summary = "获取角色关联菜单权限 @author 卓大") + @GetMapping("/role/menu/getRoleSelectedMenu/{roleId}") + public ResponseDTO getRoleSelectedMenu(@PathVariable Long roleId) { + return roleMenuService.getRoleSelectedMenu(roleId); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java new file mode 100644 index 0000000..9cb9b1e --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; + +/** + * 角色 dao + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface RoleDao extends BaseMapper { + + /** + * 根据角色名称查询 + */ + RoleEntity getByRoleName(@Param("roleName") String roleName); + + /** + * 根据角色编码 + */ + RoleEntity getByRoleCode(@Param("roleCode") String roleCode); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java new file mode 100644 index 0000000..16ddf39 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; + +import java.util.List; + + +/** + * 角色 数据权限 dao + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface RoleDataScopeDao extends BaseMapper { + + /** + * 获取某个角色的设置信息 + */ + List listByRoleId(@Param("roleId") Long roleId); + + /** + * 获取某批角色的所有数据范围配置信息 + */ + List listByRoleIdList(@Param("roleIdList") List roleIdList); + + /** + * 删除某个角色的设置信息 + */ + void deleteByRoleId(@Param("roleId") Long roleId); + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java new file mode 100644 index 0000000..71de64c --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java @@ -0,0 +1,88 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleEmployeeVO; + +import java.util.List; +import java.util.Set; + + +/** + * 角色 员工 dao + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface RoleEmployeeDao extends BaseMapper { + + /** + * 根据员工id 查询所有的角色 + */ + List selectRoleByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * 根据员工id 查询所有的角色io集合 + */ + List selectRoleIdByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * 根据员工id 查询所有的角色 + */ + List selectRoleIdByEmployeeIdList(@Param("employeeIdList") List employeeIdList); + + /** + * 根据员工id 查询所有的角色 + */ + List selectRoleByEmployeeIdList(@Param("employeeIdList") List employeeIdList); + + /** + * 查询角色下的人员id + */ + Set selectEmployeeIdByRoleIdList(@Param("roleIdList") List roleIdList); + + /** + * + */ + List selectRoleEmployeeByName(Page page, @Param("queryForm") RoleEmployeeQueryForm roleEmployeeQueryForm); + + /** + * + */ + List selectEmployeeByRoleId(@Param("roleId") Long roleId); + /** + * 根据员工信息删除 + */ + void deleteByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * 删除某个角色的所有关系 + */ + void deleteByRoleId(@Param("roleId")Long roleId); + + /** + * 根据员工和 角色删除关系 + */ + void deleteByEmployeeIdRoleId(@Param("employeeId") Long employeeId,@Param("roleId")Long roleId); + + /** + * 批量删除某个角色下的某批用户的关联关系 + */ + void batchDeleteEmployeeRole(@Param("roleId") Long roleId, @Param("employeeIds") Set employeeIds); + + /** + * 判断某个角色下是否存在用户 + */ + Integer existsByRoleId(@Param("roleId") Long roleId); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java new file mode 100644 index 0000000..dd11d84 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleMenuEntity; + +import java.util.List; + +/** + * 角色 菜单 dao + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface RoleMenuDao extends BaseMapper { + + /** + * 根据角色ID删除菜单权限 + * + */ + void deleteByRoleId(@Param("roleId") Long roleId); + + /** + * 根据角色ID查询选择的菜单权限 + * + */ + List queryMenuIdByRoleId(@Param("roleId") Long roleId); + + /** + * 根据角色ID集合查询选择的菜单权限 + * + */ + List selectMenuListByRoleIdList(@Param("roleIdList") List roleIdList, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询所有的菜单角色 + * + */ + List queryAllRoleMenu(); +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java new file mode 100644 index 0000000..40f04f5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; + +import java.time.LocalDateTime; + +/** + * 数据范围与角色关系 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_role_data_scope") +public class RoleDataScopeEntity { + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 数据范围id + * {@link DataScopeTypeEnum} + */ + private Integer dataScopeType; + /** + * 数据范围类型 + * {@link DataScopeViewTypeEnum} + */ + private Integer viewType; + /** + * 角色id + */ + private Long roleId; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java new file mode 100644 index 0000000..636bd0b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色 员工关系 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_role_employee") +public class RoleEmployeeEntity { + + @TableId(type = IdType.AUTO) + private Long id; + + private Long roleId; + + private Long employeeId; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + + public RoleEmployeeEntity() { + } + + public RoleEmployeeEntity(Long roleId, Long employeeId) { + this.roleId = roleId; + this.employeeId = employeeId; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java new file mode 100644 index 0000000..12e2219 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_role") +public class RoleEntity { + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long roleId; + + /** + * 角色名称 + */ + private String roleName; + + /** + * 角色编码 + */ + private String roleCode; + + /** + * 角色备注 + */ + private String remark; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java new file mode 100644 index 0000000..410d248 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-16 23:00:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_role_menu") +public class RoleMenuEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long roleMenuId; + + /** + * 角色 id + */ + private Long roleId; + + /** + * 菜单 id + */ + private Long menuId; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java new file mode 100644 index 0000000..0ceced6 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 角色 添加表单 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-02-26 19:09:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleAddForm { + + /** + * 角色名称 + */ + @Schema(description = "角色名称") + @NotNull(message = "角色名称不能为空") + @Length(min = 1, max = 20, message = "角色名称(1-20)个字符") + private String roleName; + + @Schema(description = "角色编码") + @NotNull(message = "角色编码 不能为空") + @Length(min = 1, max = 20, message = "角色编码(1-20)个字符") + private String roleCode; + + /** + * 角色描述 + */ + @Schema(description = "角色描述") + @Length(max = 255, message = "角色描述最多255个字符") + private String remark; + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java new file mode 100644 index 0000000..71525e3 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 角色的数据范围更新 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleDataScopeUpdateForm { + + @Schema(description = "角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + @Schema(description = "设置信息") + @Valid + private List dataScopeItemList; + + + @Data + public static class RoleUpdateDataScopeListFormItem { + + @Schema(description = "数据范围类型") + @NotNull(message = "数据范围类型不能为空") + private Integer dataScopeType; + + @Schema(description = "可见范围") + @NotNull(message = "可见范围不能为空") + private Integer viewType; + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java new file mode 100644 index 0000000..46b21e8 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +/** + * 角色的员工查询 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleEmployeeQueryForm extends PageParam { + + @Schema(description = "关键字") + private String keywords; + + @Schema(description = "角色id") + private String roleId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java new file mode 100644 index 0000000..4960b4a --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Set; + +/** + * 角色的员工更新 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleEmployeeUpdateForm { + + @Schema(description = "角色id") + @NotNull(message = "角色id不能为空") + protected Long roleId; + + @Schema(description = "员工id集合") + @NotEmpty(message = "员工id不能为空") + protected Set employeeIdList; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java new file mode 100644 index 0000000..46e6c02 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 角色的菜单更新 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleMenuUpdateForm { + + /** + * 角色id + */ + @Schema(description = "角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + /** + * 菜单ID 集合 + */ + @Schema(description = "菜单ID集合") + @NotNull(message = "菜单ID不能为空") + private List menuIdList; + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java new file mode 100644 index 0000000..cf754e4 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +/** + * 角色 查询 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-02-26 19:09:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleQueryForm extends PageParam { + + @Schema(description = "角色名称") + private String roleName; + + @Schema(description = "角色id") + private String roleId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java new file mode 100644 index 0000000..a29bf2e --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 角色更新修改 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-02-26 19:09:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleUpdateForm extends RoleAddForm { + + /** + * 角色id + */ + @Schema(description = "角色id") + @NotNull(message = "角色id不能为空") + protected Long roleId; + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java new file mode 100644 index 0000000..350b644 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 角色的数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleDataScopeVO { + + @Schema(description = "数据范围id") + private Integer dataScopeType; + + @Schema(description = "可见范围") + private Integer viewType; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java new file mode 100644 index 0000000..83d4023 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import lombok.Data; + +/** + * 角色的员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleEmployeeVO { + + private Long roleId; + + private Long employeeId; + + private String roleName; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java new file mode 100644 index 0000000..2809115 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuSimpleTreeVO; + +import java.util.List; + +/** + * 角色菜单树 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleMenuTreeVO { + + @Schema(description = "角色ID") + private Long roleId; + + @Schema(description = "菜单列表") + private List menuTreeList; + + @Schema(description = "选中的菜单ID") + private List selectedMenuId; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java new file mode 100644 index 0000000..1165cff --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 选择角色 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleSelectedVO extends RoleVO { + + @Schema(description = "角色名称") + private Boolean selected; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java new file mode 100644 index 0000000..767cda9 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 角色 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RoleVO { + + @Schema(description = "角色ID") + private Long roleId; + + @Schema(description = "角色名称") + private String roleName; + + @Schema(description = "角色编码") + private String roleCode; + + @Schema(description = "角色备注") + private String remark; +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java new file mode 100644 index 0000000..bc9e0a4 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.role.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.role.dao.RoleDataScopeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; +import org.springframework.stereotype.Service; + +/** + * 角色 数据范围 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleDataScopeManager extends ServiceImpl { + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java new file mode 100644 index 0000000..ba33dfd --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.role.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import org.springframework.stereotype.Service; + +/** + * 角色员工 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleEmployeeManager extends ServiceImpl { + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java new file mode 100644 index 0000000..8ee4bc5 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.admin.module.system.role.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleMenuEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 角色-菜单 manager + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-09 19:05:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleMenuManager extends ServiceImpl { + + @Resource + private RoleMenuDao roleMenuDao; + + /** + * 更新角色权限 + * + */ + @Transactional(rollbackFor = Exception.class) + public void updateRoleMenu(Long roleId, List roleMenuEntityList) { + // 根据角色ID删除菜单权限 + roleMenuDao.deleteByRoleId(roleId); + // 批量添加菜单权限 + saveBatch(roleMenuEntityList); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java new file mode 100644 index 0000000..f73a852 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java @@ -0,0 +1,63 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleDataScopeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleDataScopeVO; +import net.lab1024.sa.admin.module.system.role.manager.RoleDataScopeManager; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 角色-数据范围 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021-10-22 23:17:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleDataScopeService { + + @Resource + private RoleDataScopeManager roleDataScopeManager; + + + /** + * 获取某个角色的数据范围设置信息 + * + */ + public ResponseDTO> getRoleDataScopeList(Long roleId) { + List roleDataScopeEntityList = roleDataScopeManager.getBaseMapper().listByRoleId(roleId); + if (CollectionUtils.isEmpty(roleDataScopeEntityList)) { + return ResponseDTO.ok(Lists.newArrayList()); + } + List roleDataScopeList = SmartBeanUtil.copyList(roleDataScopeEntityList, RoleDataScopeVO.class); + return ResponseDTO.ok(roleDataScopeList); + } + + /** + * 批量设置某个角色的数据范围设置信息 + * + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateRoleDataScopeList(RoleDataScopeUpdateForm roleDataScopeUpdateForm) { + List batchSetList = roleDataScopeUpdateForm.getDataScopeItemList(); + if (CollectionUtils.isEmpty(batchSetList)) { + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "缺少配置信息"); + } + List roleDataScopeEntityList = SmartBeanUtil.copyList(batchSetList, RoleDataScopeEntity.class); + roleDataScopeEntityList.forEach(e -> e.setRoleId(roleDataScopeUpdateForm.getRoleId())); + roleDataScopeManager.getBaseMapper().deleteByRoleId(roleDataScopeUpdateForm.getRoleId()); + roleDataScopeManager.saveBatch(roleDataScopeEntityList); + return ResponseDTO.ok(); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java new file mode 100644 index 0000000..b44430e --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java @@ -0,0 +1,154 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleSelectedVO; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.admin.module.system.role.manager.RoleEmployeeManager; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 角色-员工 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021-10-22 23:17:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleEmployeeService { + + @Resource + private RoleEmployeeDao roleEmployeeDao; + @Resource + private RoleDao roleDao; + @Resource + private DepartmentDao departmentDao; + @Resource + private RoleEmployeeManager roleEmployeeManager; + + + /** + * 批量插入 + * + */ + public void batchInsert(List roleEmployeeList) { + roleEmployeeManager.saveBatch(roleEmployeeList); + } + + /** + * 通过角色id,分页获取成员员工列表 + * + */ + public ResponseDTO> queryEmployee(RoleEmployeeQueryForm roleEmployeeQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(roleEmployeeQueryForm); + List employeeList = roleEmployeeDao.selectRoleEmployeeByName(page, roleEmployeeQueryForm) + .stream() + .filter(Objects::nonNull) + .collect(Collectors.toList()); + List departmentIdList = employeeList.stream().filter(e -> e != null && e.getDepartmentId() != null).map(EmployeeVO::getDepartmentId).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(departmentIdList)) { + List departmentEntities = departmentDao.selectBatchIds(departmentIdList); + Map departmentIdNameMap = departmentEntities.stream().collect(Collectors.toMap(DepartmentEntity::getDepartmentId, DepartmentEntity::getDepartmentName)); + employeeList.forEach(e -> { + e.setDepartmentName(departmentIdNameMap.getOrDefault(e.getDepartmentId(), StringConst.EMPTY)); + }); + } + PageResult pageResult = SmartPageUtil.convert2PageResult(page, employeeList, EmployeeVO.class); + return ResponseDTO.ok(pageResult); + } + + public List getAllEmployeeByRoleId(Long roleId) { + return roleEmployeeDao.selectEmployeeByRoleId(roleId); + } + + /** + * 移除员工角色 + * + */ + public ResponseDTO removeRoleEmployee(Long employeeId, Long roleId) { + if (null == employeeId || null == roleId) { + return ResponseDTO.userErrorParam(); + } + roleEmployeeDao.deleteByEmployeeIdRoleId(employeeId, roleId); + return ResponseDTO.ok(); + } + + /** + * 批量删除角色的成员员工 + * + */ + public ResponseDTO batchRemoveRoleEmployee(RoleEmployeeUpdateForm roleEmployeeUpdateForm) { + roleEmployeeDao.batchDeleteEmployeeRole(roleEmployeeUpdateForm.getRoleId(), roleEmployeeUpdateForm.getEmployeeIdList()); + return ResponseDTO.ok(); + } + + /** + * 批量添加角色的成员员工 + * + */ + public ResponseDTO batchAddRoleEmployee(RoleEmployeeUpdateForm roleEmployeeUpdateForm) { + Long roleId = roleEmployeeUpdateForm.getRoleId(); + + // 已选择的员工id列表 + Set selectedEmployeeIdList = roleEmployeeUpdateForm.getEmployeeIdList(); + // 数据库里已有的员工id列表 + Set dbEmployeeIdList = roleEmployeeDao.selectEmployeeIdByRoleIdList(Lists.newArrayList(roleId)); + // 从已选择的员工id列表里 过滤数据库里不存在的 即需要添加的员工 id + Set addEmployeeIdList = selectedEmployeeIdList.stream().filter(id -> !dbEmployeeIdList.contains(id)).collect(Collectors.toSet()); + + // 添加角色员工 + if (CollectionUtils.isNotEmpty(addEmployeeIdList)) { + List roleEmployeeList = addEmployeeIdList.stream() + .map(employeeId -> new RoleEmployeeEntity(roleId, employeeId)) + .collect(Collectors.toList()); + roleEmployeeManager.saveBatch(roleEmployeeList); + } + return ResponseDTO.ok(); + } + + /** + * 通过员工id获取员工角色 + * + */ + public List getRoleInfoListByEmployeeId(Long employeeId) { + List roleIds = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + List roleList = roleDao.selectList(null); + List result = SmartBeanUtil.copyList(roleList, RoleSelectedVO.class); + result.stream().forEach(item -> item.setSelected(roleIds.contains(item.getRoleId()))); + return result; + } + + /** + * 根据员工id 查询角色id集合 + * + */ + public List getRoleIdList(Long employeeId) { + return roleEmployeeDao.selectRoleByEmployeeId(employeeId); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java new file mode 100644 index 0000000..9d25bce --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java @@ -0,0 +1,123 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuSimpleTreeVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleMenuEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleMenuUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleMenuTreeVO; +import net.lab1024.sa.admin.module.system.role.manager.RoleMenuManager; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 角色-菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021-10-22 23:17:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleMenuService { + + @Resource + private RoleDao roleDao; + @Resource + private RoleMenuDao roleMenuDao; + @Resource + private RoleMenuManager roleMenuManager; + @Resource + private MenuDao menuDao; + + /** + * 更新角色权限 + * + */ + public ResponseDTO updateRoleMenu(RoleMenuUpdateForm roleMenuUpdateForm) { + //查询角色是否存在 + Long roleId = roleMenuUpdateForm.getRoleId(); + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + List roleMenuEntityList = Lists.newArrayList(); + RoleMenuEntity roleMenuEntity; + for (Long menuId : roleMenuUpdateForm.getMenuIdList()) { + roleMenuEntity = new RoleMenuEntity(); + roleMenuEntity.setRoleId(roleId); + roleMenuEntity.setMenuId(menuId); + roleMenuEntityList.add(roleMenuEntity); + } + roleMenuManager.updateRoleMenu(roleMenuUpdateForm.getRoleId(), roleMenuEntityList); + return ResponseDTO.ok(); + } + + /** + * 根据角色id集合,查询其所有的菜单权限 + * + */ + public List getMenuList(List roleIdList, Boolean administratorFlag) { + //管理员返回所有菜单 + if(administratorFlag){ + List menuEntityList = roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(), false); + return SmartBeanUtil.copyList(menuEntityList, MenuVO.class); + } + //非管理员 无角色 返回空菜单 + if (CollectionUtils.isEmpty(roleIdList)) { + return new ArrayList<>(); + } + List menuEntityList = roleMenuDao.selectMenuListByRoleIdList(roleIdList, false); + return SmartBeanUtil.copyList(menuEntityList, MenuVO.class); + } + + + /** + * 获取角色关联菜单权限 + * + */ + public ResponseDTO getRoleSelectedMenu(Long roleId) { + RoleMenuTreeVO res = new RoleMenuTreeVO(); + res.setRoleId(roleId); + //查询角色ID选择的菜单权限 + List selectedMenuId = roleMenuDao.queryMenuIdByRoleId(roleId); + res.setSelectedMenuId(selectedMenuId); + //查询菜单权限 + List menuVOList = menuDao.queryMenuList(Boolean.FALSE, Boolean.FALSE, null); + Map> parentMap = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId, Collectors.toList())); + List menuTreeList = this.buildMenuTree(parentMap, NumberUtils.LONG_ZERO); + res.setMenuTreeList(menuTreeList); + return ResponseDTO.ok(res); + } + + /** + * 构建菜单树 + * + */ + private List buildMenuTree(Map> parentMap, Long parentId) { + // 获取本级菜单树List + List res = parentMap.getOrDefault(parentId, Lists.newArrayList()).stream() + .map(e -> SmartBeanUtil.copy(e, MenuSimpleTreeVO.class)).collect(Collectors.toList()); + // 循环遍历下级菜单 + res.forEach(e -> { + e.setChildren(this.buildMenuTree(parentMap, e.getMenuId())); + }); + return res; + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java new file mode 100644 index 0000000..2d01b4b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java @@ -0,0 +1,123 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleAddForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 角色 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-08-16 20:19:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RoleService { + + @Resource + private RoleDao roleDao; + + @Resource + private RoleMenuDao roleMenuDao; + + @Resource + private RoleEmployeeDao roleEmployeeDao; + + /** + * 新增添加角色 + */ + public ResponseDTO addRole(RoleAddForm roleAddForm) { + RoleEntity existRoleEntity = roleDao.getByRoleName(roleAddForm.getRoleName()); + if (null != existRoleEntity) { + return ResponseDTO.userErrorParam("角色名称重复"); + } + + existRoleEntity = roleDao.getByRoleCode(roleAddForm.getRoleCode()); + if (null != existRoleEntity) { + return ResponseDTO.userErrorParam("角色编码重复,重复的角色为:" + existRoleEntity.getRoleName()); + } + + RoleEntity roleEntity = SmartBeanUtil.copy(roleAddForm, RoleEntity.class); + roleDao.insert(roleEntity); + return ResponseDTO.ok(); + } + + /** + * 根据角色id 删除 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteRole(Long roleId) { + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 当没有员工绑定这个角色时才可以删除 + Integer exists = roleEmployeeDao.existsByRoleId(roleId); + if (exists != null) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, "该角色下存在员工,无法删除"); + } + roleDao.deleteById(roleId); + roleMenuDao.deleteByRoleId(roleId); + roleEmployeeDao.deleteByRoleId(roleId); + return ResponseDTO.ok(); + } + + /** + * 更新角色 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateRole(RoleUpdateForm roleUpdateForm) { + if (null == roleDao.selectById(roleUpdateForm.getRoleId())) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + RoleEntity existRoleEntity = roleDao.getByRoleName(roleUpdateForm.getRoleName()); + if (null != existRoleEntity && !existRoleEntity.getRoleId().equals(roleUpdateForm.getRoleId())) { + return ResponseDTO.userErrorParam("角色名称重复"); + } + + existRoleEntity = roleDao.getByRoleCode(roleUpdateForm.getRoleCode()); + if (null != existRoleEntity && !existRoleEntity.getRoleId().equals(roleUpdateForm.getRoleId())) { + return ResponseDTO.userErrorParam("角色编码重复,重复的角色为:" + existRoleEntity.getRoleName()); + } + + RoleEntity roleEntity = SmartBeanUtil.copy(roleUpdateForm, RoleEntity.class); + roleDao.updateById(roleEntity); + return ResponseDTO.ok(); + } + + /** + * 根据id获取角色数据 + */ + public ResponseDTO getRoleById(Long roleId) { + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + RoleVO role = SmartBeanUtil.copy(roleEntity, RoleVO.class); + return ResponseDTO.ok(role); + } + + /** + * 获取所有角色列表 + */ + public ResponseDTO> getAllRole() { + List roleEntityList = roleDao.selectList(null); + List roleList = SmartBeanUtil.copyList(roleEntityList, RoleVO.class); + return ResponseDTO.ok(roleList); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController.java new file mode 100644 index 0000000..cc79672 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController.java @@ -0,0 +1,81 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import lombok.Data; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiDecrypt; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiEncrypt; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * + * api 加密 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 09:21:20 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@RestController +@Tag(name = SwaggerTagConst.Support.PROTECT) +public class AdminApiEncryptController extends SupportBaseController { + + + @ApiDecrypt + @PostMapping("/apiEncrypt/testRequestEncrypt") + @Operation(summary = "测试 请求加密") + public ResponseDTO testRequestEncrypt(@RequestBody @Valid JweForm form) { + return ResponseDTO.ok(form); + } + + @ApiEncrypt + @PostMapping("/apiEncrypt/testResponseEncrypt") + @Operation(summary = "测试 返回加密") + public ResponseDTO testResponseEncrypt(@RequestBody @Valid JweForm form) { + return ResponseDTO.ok(form); + } + + @ApiDecrypt + @ApiEncrypt + @PostMapping("/apiEncrypt/testDecryptAndEncrypt") + @Operation(summary = "测试 请求参数加密和解密、返回数据加密和解密") + public ResponseDTO testDecryptAndEncrypt(@RequestBody @Valid JweForm form) { + return ResponseDTO.ok(form); + } + + @ApiDecrypt + @ApiEncrypt + @PostMapping("/apiEncrypt/testArray") + @Operation(summary = "测试 数组加密和解密") + public ResponseDTO> testArray(@RequestBody @Valid ValidateList list) { + return ResponseDTO.ok(list); + } + + + @Data + public static class JweForm { + + @NotBlank(message = "姓名 不能为空") + String name; + + @NotNull + @Min(value = 1) + Integer age; + + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java new file mode 100644 index 0000000..2c318c8 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.cache.CacheService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 缓存 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/11 20:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.CACHE) +public class AdminCacheController extends SupportBaseController { + + @Resource + private CacheService cacheService; + + @Operation(summary = "获取所有缓存 @author 罗伊") + @GetMapping("/cache/names") + @SaCheckPermission("support:cache:keys") + public ResponseDTO> cacheNames() { + return ResponseDTO.ok(cacheService.cacheNames()); + } + + @Operation(summary = "移除某个缓存 @author 罗伊") + @GetMapping("/cache/remove/{cacheName}") + @SaCheckPermission("support:cache:delete") + public ResponseDTO removeCache(@PathVariable String cacheName) { + cacheService.removeCache(cacheName); + return ResponseDTO.ok(); + } + + @Operation(summary = "获取某个缓存的所有key @author 罗伊") + @GetMapping("/cache/keys/{cacheName}") + @SaCheckPermission("support:cache:keys") + public ResponseDTO> cacheKeys(@PathVariable String cacheName) { + return ResponseDTO.ok(cacheService.cacheKey(cacheName)); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java new file mode 100644 index 0000000..05897f3 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java @@ -0,0 +1,60 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogAddForm; +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogUpdateForm; +import net.lab1024.sa.base.module.support.changelog.service.ChangeLogService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 系统更新日志 Controller + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@RestController +@Tag(name = SwaggerTagConst.Support.CHANGE_LOG) +public class AdminChangeLogController extends SupportBaseController { + + @Resource + private ChangeLogService changeLogService; + + @Operation(summary = "添加 @author 卓大") + @PostMapping("/changeLog/add") + @SaCheckPermission("support:changeLog:add") + public ResponseDTO add(@RequestBody @Valid ChangeLogAddForm addForm) { + return changeLogService.add(addForm); + } + + @Operation(summary = "更新 @author 卓大") + @PostMapping("/changeLog/update") + @SaCheckPermission("support:changeLog:update") + public ResponseDTO update(@RequestBody @Valid ChangeLogUpdateForm updateForm) { + return changeLogService.update(updateForm); + } + + @Operation(summary = "批量删除 @author 卓大") + @PostMapping("/changeLog/batchDelete") + @SaCheckPermission("support:changeLog:batchDelete") + public ResponseDTO batchDelete(@RequestBody ValidateList idList) { + return changeLogService.batchDelete(idList); + } + + @Operation(summary = "单个删除 @author 卓大") + @GetMapping("/changeLog/delete/{changeLogId}") + @SaCheckPermission("support:changeLog:delete") + public ResponseDTO batchDelete(@PathVariable Long changeLogId) { + return changeLogService.delete(changeLogId); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java new file mode 100644 index 0000000..b16e920 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.config.ConfigService; +import net.lab1024.sa.base.module.support.config.domain.ConfigAddForm; +import net.lab1024.sa.base.module.support.config.domain.ConfigQueryForm; +import net.lab1024.sa.base.module.support.config.domain.ConfigUpdateForm; +import net.lab1024.sa.base.module.support.config.domain.ConfigVO; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.CONFIG) +@RestController +public class AdminConfigController extends SupportBaseController { + + @Resource + private ConfigService configService; + + @Operation(summary = "分页查询系统配置 @author 卓大") + @PostMapping("/config/query") + @SaCheckPermission("support:config:query") + public ResponseDTO> queryConfigPage(@RequestBody @Valid ConfigQueryForm queryForm) { + return configService.queryConfigPage(queryForm); + } + + @Operation(summary = "添加配置参数 @author 卓大") + @PostMapping("/config/add") + @SaCheckPermission("support:config:add") + public ResponseDTO addConfig(@RequestBody @Valid ConfigAddForm configAddForm) { + return configService.add(configAddForm); + } + + @Operation(summary = "修改配置参数 @author 卓大") + @PostMapping("/config/update") + @SaCheckPermission("support:config:update") + public ResponseDTO updateConfig(@RequestBody @Valid ConfigUpdateForm updateForm) { + return configService.updateConfig(updateForm); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController.java new file mode 100644 index 0000000..7e6156b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController.java @@ -0,0 +1,88 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.hutool.core.util.RandomUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.Data; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.datamasking.DataMasking; +import net.lab1024.sa.base.module.support.datamasking.DataMaskingTypeEnum; +import org.apache.commons.lang3.RandomStringUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +/** + * 数据脱敏demo + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2024/08/01 22:07:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@RestController +@Tag(name = SwaggerTagConst.Support.DATA_MASKING) +public class AdminDataMaskingDemoController extends SupportBaseController { + + @Operation(summary = "数据脱敏demo @author 1024创新实验室-主任-卓大") + @GetMapping("/dataMasking/demo/query") + public ResponseDTO> query() { + + List list = new ArrayList<>(); + for (int i = 0; i < RandomUtil.randomInt(10,16); i++) { + DataVO data = new DataVO(); + data.setUserId(RandomUtil.randomLong(1328479238, 83274298347982L)); + data.setPhone("1" + RandomUtil.randomNumbers(10)); + data.setIdCard("410" + RandomUtil.randomNumbers(3) + RandomUtil.randomInt(1980, 2010) + RandomUtil.randomInt(10, 12) + RandomUtil.randomInt(10, 30) + RandomUtil.randomNumbers(4)); + data.setAddress(RandomUtil.randomBoolean() ? "河南省洛阳市洛龙区一零二四大街1024号" : "河南省郑州市高新区六边形大街六边形大楼"); + data.setPassword(RandomUtil.randomString(10)); + data.setEmail(RandomUtil.randomString(RandomUtil.randomInt(6, 10)) + "@" + RandomUtil.randomString(2) + ".com"); + data.setCarLicense("豫" + RandomStringUtils.randomAlphabetic(1).toUpperCase()+" " + RandomStringUtils.randomAlphanumeric(5).toUpperCase()); + data.setBankCard("6225" + RandomStringUtils.randomNumeric(14)); + data.setOther(RandomStringUtils.randomAlphanumeric(1, 12)); + list.add(data); + } + + return ResponseDTO.ok(list); + } + + + @Data + public static class DataVO { + + @DataMasking(DataMaskingTypeEnum.USER_ID) + private Long userId; + + @DataMasking(DataMaskingTypeEnum.PHONE) + private String phone; + + @DataMasking(DataMaskingTypeEnum.ID_CARD) + private String idCard; + + @DataMasking(DataMaskingTypeEnum.ADDRESS) + private String address; + + @DataMasking(DataMaskingTypeEnum.PASSWORD) + private String password; + + @DataMasking(DataMaskingTypeEnum.EMAIL) + private String email; + + @DataMasking(DataMaskingTypeEnum.CAR_LICENSE) + private String carLicense; + + @DataMasking(DataMaskingTypeEnum.BANK_CARD) + private String bankCard; + + @DataMasking + private String other; + + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java new file mode 100644 index 0000000..3a7327b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java @@ -0,0 +1,139 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.dict.domain.form.*; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictDataVO; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictVO; +import net.lab1024.sa.base.module.support.dict.service.DictService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 数据字典 Controller + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.DICT) +@RestController +public class AdminDictController extends SupportBaseController { + + @Resource + private DictService dictService; + + // ------------------- 获取全部数据 ------------------- + + @Operation(summary = "获取全部数据(供前端缓存使用) @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/getAllDictData") + public ResponseDTO> getAll() { + return ResponseDTO.ok(dictService.getAll()); + } + + @Operation(summary = "获取所有字典code @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/getAllDict") + public ResponseDTO> getAllDict() { + return ResponseDTO.ok(dictService.getAllDict()); + } + + // ------------------- 字典 ------------------- + + @Operation(summary = "分页查询 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/queryPage") + @SaCheckPermission("support:dict:query") + public ResponseDTO> queryPage(@RequestBody @Valid DictQueryForm queryForm) { + return ResponseDTO.ok(dictService.queryPage(queryForm)); + } + + @Operation(summary = "添加 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/add") + @SaCheckPermission("support:dict:add") + public ResponseDTO add(@RequestBody @Valid DictAddForm addForm) { + return dictService.add(addForm); + } + + @Operation(summary = "更新 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/update") + @SaCheckPermission("support:dict:update") + public ResponseDTO update(@RequestBody @Valid DictUpdateForm updateForm) { + return dictService.update(updateForm); + } + + @Operation(summary = "启用/禁用 @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/updateDisabled/{dictId}") + @SaCheckPermission("support:dict:updateDisabled") + public ResponseDTO updateDisabled(@PathVariable Long dictId) { + return dictService.updateDisabled(dictId); + } + + @Operation(summary = "批量删除 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/batchDelete") + @SaCheckPermission("support:dict:delete") + public ResponseDTO batchDelete(@RequestBody ValidateList idList) { + return dictService.batchDelete(idList); + } + + @Operation(summary = "单个删除 @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/delete/{dictId}") + @SaCheckPermission("support:dict:delete") + public ResponseDTO delete(@PathVariable Long dictId) { + return dictService.delete(dictId); + } + + // ------------------- 字典数据 ------------------- + + @Operation(summary = "字典数据 分页查询 @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/dictData/queryDictData/{dictId}") + @SaCheckPermission("support:dictData:query") + public ResponseDTO> queryDictData(@PathVariable Long dictId) { + return ResponseDTO.ok(dictService.queryDictData(dictId)); + } + + @Operation(summary = "字典数据 启用/禁用 @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/dictData/updateDisabled/{dictDataId}") + @SaCheckPermission("support:dictData:updateDisabled") + public ResponseDTO updateDictDataDisabled(@PathVariable Long dictDataId) { + return dictService.updateDictDataDisabled(dictDataId); + } + + @Operation(summary = "字典数据 添加 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/dictData/add") + @SaCheckPermission("support:dictData:add") + public ResponseDTO addDictData(@RequestBody @Valid DictDataAddForm addForm) { + return dictService.addDictData(addForm); + } + + @Operation(summary = "字典数据 更新 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/dictData/update") + @SaCheckPermission("support:dictData:update") + public ResponseDTO updateDictData(@RequestBody @Valid DictDataUpdateForm updateForm) { + return dictService.updateDictData(updateForm); + } + + @Operation(summary = "字典数据 批量删除 @author 1024创新实验室-主任-卓大") + @PostMapping("/dict/dictData/batchDelete") + @SaCheckPermission("support:dictData:delete") + public ResponseDTO batchDeleteDictData(@RequestBody ValidateList idList) { + return dictService.batchDeleteDictData(idList); + } + + @Operation(summary = "字典数据 单个删除 @author 1024创新实验室-主任-卓大") + @GetMapping("/dict/dictData/delete/{dictDataId}") + @SaCheckPermission("support:dictData:delete") + public ResponseDTO deleteDictData(@PathVariable Long dictDataId) { + return dictService.deleteDictData(dictDataId); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java new file mode 100644 index 0000000..453d374 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.file.domain.form.FileQueryForm; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.base.module.support.file.service.FileService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.FILE) +public class AdminFileController extends SupportBaseController { + + @Resource + private FileService fileService; + + @Operation(summary = "分页查询 @author 1024创新实验室-主任-卓大") + @PostMapping("/file/queryPage") + @SaCheckPermission("support:file:query") + public ResponseDTO> queryPage(@RequestBody @Valid FileQueryForm queryForm) { + return ResponseDTO.ok(fileService.queryPage(queryForm)); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java new file mode 100644 index 0000000..f9aaf6e --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.heartbeat.HeartBeatService; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordQueryForm; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordVO; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.HEART_BEAT) +@RestController +public class AdminHeartBeatController extends SupportBaseController { + + @Resource + private HeartBeatService heartBeatService; + + @PostMapping("/heartBeat/query") + @Operation(summary = "查询心跳记录 @author 卓大") + public ResponseDTO> query(@RequestBody @Valid HeartBeatRecordQueryForm pageParam) { + return heartBeatService.pageQuery(pageParam); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java new file mode 100644 index 0000000..51f1d1f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java @@ -0,0 +1,104 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.*; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.base.module.support.helpdoc.service.HelpDocCatalogService; +import net.lab1024.sa.base.module.support.helpdoc.service.HelpDocService; +import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.HELP_DOC) +@RestController +public class AdminHelpDocController extends SupportBaseController { + + @Resource + private HelpDocService helpDocService; + + @Resource + private HelpDocCatalogService helpDocCatalogService; + + // --------------------- 帮助文档 【目录管理】 ------------------------- + + + @Operation(summary = "帮助文档目录-添加 @author 卓大") + @PostMapping("/helpDoc/helpDocCatalog/add") + public ResponseDTO addHelpDocCatalog(@RequestBody @Valid HelpDocCatalogAddForm helpDocCatalogAddForm) { + return helpDocCatalogService.add(helpDocCatalogAddForm); + } + + @Operation(summary = "帮助文档目录-更新 @author 卓大") + @PostMapping("/helpDoc/helpDocCatalog/update") + public ResponseDTO updateHelpDocCatalog(@RequestBody @Valid HelpDocCatalogUpdateForm helpDocCatalogUpdateForm) { + return helpDocCatalogService.update(helpDocCatalogUpdateForm); + } + + @Operation(summary = "帮助文档目录-删除 @author 卓大") + @GetMapping("/helpDoc/helpDocCatalog/delete/{helpDocCatalogId}") + public ResponseDTO deleteHelpDocCatalog(@PathVariable Long helpDocCatalogId) { + return helpDocCatalogService.delete(helpDocCatalogId); + } + + // --------------------- 帮助文档 【管理:增、删、查、改】------------------------- + + @Operation(summary = "【管理】帮助文档-分页查询 @author 卓大") + @PostMapping("/helpDoc/query") + @SaCheckPermission("support:helpDoc:query") + public ResponseDTO> query(@RequestBody @Valid HelpDocQueryForm queryForm) { + return ResponseDTO.ok(helpDocService.query(queryForm)); + } + + @Operation(summary = "【管理】帮助文档-获取详情 @author 卓大") + @GetMapping("/helpDoc/getDetail/{helpDocId}") + @SaCheckPermission("support:helpDoc:add") + public ResponseDTO getDetail(@PathVariable Long helpDocId) { + return ResponseDTO.ok(helpDocService.getDetail(helpDocId)); + } + + @Operation(summary = "【管理】帮助文档-添加 @author 卓大") + @PostMapping("/helpDoc/add") + @RepeatSubmit + public ResponseDTO add(@RequestBody @Valid HelpDocAddForm addForm) { + return helpDocService.add(addForm); + } + + @Operation(summary = "【管理】帮助文档-更新 @author 卓大") + @PostMapping("/helpDoc/update") + @RepeatSubmit + public ResponseDTO update(@RequestBody @Valid HelpDocUpdateForm updateForm) { + return helpDocService.update(updateForm); + } + + @Operation(summary = "【管理】帮助文档-删除 @author 卓大") + @GetMapping("/helpDoc/delete/{helpDocId}") + public ResponseDTO delete(@PathVariable Long helpDocId) { + return helpDocService.delete(helpDocId); + } + + @Operation(summary = "【管理】帮助文档-根据关联id查询 @author 卓大") + @GetMapping("/helpDoc/queryHelpDocByRelationId/{relationId}") + public ResponseDTO> queryHelpDocByRelationId(@PathVariable Long relationId) { + return ResponseDTO.ok(helpDocService.queryHelpDocByRelationId(relationId)); + } + +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java new file mode 100644 index 0000000..ba3f5a0 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.loginlog.LoginLogService; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogQueryForm; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogVO; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.LOGIN_LOG) +public class AdminLoginLogController extends SupportBaseController { + + @Resource + private LoginLogService loginLogService; + + @Operation(summary = "分页查询 @author 卓大") + @PostMapping("/loginLog/page/query") + @SaCheckPermission("support:loginLog:query") + public ResponseDTO> queryByPage(@RequestBody LoginLogQueryForm queryForm) { + return loginLogService.queryByPage(queryForm); + } + + @Operation(summary = "分页查询当前登录人信息 @author 善逸") + @PostMapping("/loginLog/page/query/login") + public ResponseDTO> queryByPageLogin(@RequestBody LoginLogQueryForm queryForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + queryForm.setUserId(requestUser.getUserId()); + queryForm.setUserType(requestUser.getUserType().getValue()); + return loginLogService.queryByPage(queryForm); + } + + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java new file mode 100644 index 0000000..8624cbc --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.operatelog.OperateLogService; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogQueryForm; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogVO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * 操作日志 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.OPERATE_LOG) +public class AdminOperateLogController extends SupportBaseController { + + @Resource + private OperateLogService operateLogService; + + @Operation(summary = "分页查询 @author 罗伊") + @PostMapping("/operateLog/page/query") + @SaCheckPermission("support:operateLog:query") + public ResponseDTO> queryByPage(@RequestBody OperateLogQueryForm queryForm) { + return operateLogService.queryByPage(queryForm); + } + + @Operation(summary = "详情 @author 罗伊") + @GetMapping("/operateLog/detail/{operateLogId}") + @SaCheckPermission("support:operateLog:detail") + public ResponseDTO detail(@PathVariable Long operateLogId) { + return operateLogService.detail(operateLogId); + } + + @Operation(summary = "分页查询当前登录人信息 @author 善逸") + @PostMapping("/operateLog/page/query/login") + public ResponseDTO> queryByPageLogin(@RequestBody OperateLogQueryForm queryForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + queryForm.setOperateUserId(requestUser.getUserId()); + queryForm.setOperateUserType(requestUser.getUserType().getValue()); + return operateLogService.queryByPage(queryForm); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminProtectController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminProtectController.java new file mode 100644 index 0000000..aa25bec --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminProtectController.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.base.module.support.config.ConfigService; +import net.lab1024.sa.base.module.support.securityprotect.domain.Level3ProtectConfigForm; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailQueryForm; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailVO; +import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService; +import net.lab1024.sa.base.module.support.securityprotect.service.SecurityLoginService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 网络安全 + * */ + +@RestController +@Tag(name = SwaggerTagConst.Support.PROTECT) +public class AdminProtectController extends SupportBaseController { + + @Resource + private SecurityLoginService securityLoginService; + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + @Resource + private ConfigService configService; + + + @Operation(summary = "分页查询 @author 1024创新实验室-主任-卓大") + @PostMapping("/protect/loginFail/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid LoginFailQueryForm queryForm) { + return ResponseDTO.ok(securityLoginService.queryPage(queryForm)); + } + + + @Operation(summary = "批量删除 @author 1024创新实验室-主任-卓大") + @PostMapping("/protect/loginFail/batchDelete") + public ResponseDTO batchDelete(@RequestBody ValidateList idList) { + return securityLoginService.batchDelete(idList); + } + + @Operation(summary = "更新三级等保配置 @author 1024创新实验室-主任-卓大") + @PostMapping("/protect/level3protect/updateConfig") + public ResponseDTO updateConfig(@RequestBody @Valid Level3ProtectConfigForm configForm) { + return level3ProtectConfigService.updateLevel3Config(configForm); + } + + @Operation(summary = "查询 三级等保配置 @author 1024创新实验室-主任-卓大") + @GetMapping("/protect/level3protect/getConfig") + public ResponseDTO getConfig() { + return ResponseDTO.ok(configService.getConfigValue(ConfigKeyEnum.LEVEL3_PROTECT_CONFIG)); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java new file mode 100644 index 0000000..b8f3214 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.reload.ReloadService; +import net.lab1024.sa.base.module.support.reload.domain.ReloadForm; +import net.lab1024.sa.base.module.support.reload.domain.ReloadItemVO; +import net.lab1024.sa.base.module.support.reload.domain.ReloadResultVO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.RELOAD) +public class AdminReloadController extends SupportBaseController { + + @Resource + private ReloadService reloadService; + + @Operation(summary = "查询reload列表 @author 开云") + @GetMapping("/reload/query") + public ResponseDTO> query() { + return reloadService.query(); + } + + @Operation(summary = "获取reload result @author 开云") + @GetMapping("/reload/result/{tag}") + @SaCheckPermission("support:reload:result") + public ResponseDTO> queryReloadResult(@PathVariable("tag") String tag) { + return reloadService.queryReloadItemResult(tag); + } + + @Operation(summary = "通过tag更新标识 @author 开云") + @PostMapping("/reload/update") + @SaCheckPermission("support:reload:update") + public ResponseDTO updateByTag(@RequestBody @Valid ReloadForm reloadForm) { + return reloadService.updateByTag(reloadForm); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java new file mode 100644 index 0000000..df49269 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.admin.module.system.support; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.base.module.support.serialnumber.dao.SerialNumberDao; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberGenerateForm; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberRecordEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberRecordQueryForm; +import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberRecordService; +import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +/** + * 单据序列号 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.SERIAL_NUMBER) +@RestController +public class AdminSerialNumberController extends SupportBaseController { + + @Resource + private SerialNumberDao serialNumberDao; + + @Resource + private SerialNumberService serialNumberService; + + @Resource + private SerialNumberRecordService serialNumberRecordService; + + @Operation(summary = "生成单号 @author 卓大") + @PostMapping("/serialNumber/generate") + @SaCheckPermission("support:serialNumber:generate") + public ResponseDTO> generate(@RequestBody @Valid SerialNumberGenerateForm generateForm) { + SerialNumberIdEnum serialNumberIdEnum = SmartEnumUtil.getEnumByValue(generateForm.getSerialNumberId(), SerialNumberIdEnum.class); + if (null == serialNumberIdEnum) { + return ResponseDTO.userErrorParam("SerialNumberId,不存在" + generateForm.getSerialNumberId()); + } + return ResponseDTO.ok(serialNumberService.generate(serialNumberIdEnum, generateForm.getCount())); + } + + @Operation(summary = "获取所有单号定义 @author 卓大") + @GetMapping("/serialNumber/all") + public ResponseDTO> getAll() { + return ResponseDTO.ok(serialNumberDao.selectList(null)); + } + + @Operation(summary = "获取生成记录 @author 卓大") + @PostMapping("/serialNumber/queryRecord") + @SaCheckPermission("support:serialNumber:record") + public ResponseDTO> queryRecord(@RequestBody @Valid SerialNumberRecordQueryForm queryForm) { + return ResponseDTO.ok(serialNumberRecordService.query(queryForm)); + } + +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSmartJobController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSmartJobController.java new file mode 100644 index 0000000..b7dc11f --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSmartJobController.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.job.api.SmartJobService; +import net.lab1024.sa.base.module.support.job.api.domain.*; +import net.lab1024.sa.base.module.support.job.config.SmartJobAutoConfiguration; +import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 定时任务 管理接口 + * + * @author huke + * @date 2024/6/17 20:41 + */ +@Tag(name = SwaggerTagConst.Support.JOB) +@RestController +@ConditionalOnBean(SmartJobAutoConfiguration.class) +public class AdminSmartJobController extends SupportBaseController { + + @Autowired + private SmartJobService jobService; + + @Operation(summary = "定时任务-立即执行 @huke") + @PostMapping("/job/execute") + @RepeatSubmit + public ResponseDTO execute(@RequestBody @Valid SmartJobExecuteForm executeForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + executeForm.setUpdateName(requestUser.getUserName()); + return jobService.execute(executeForm); + } + + @Operation(summary = "定时任务-查询详情 @huke") + @GetMapping("/job/{jobId}") + public ResponseDTO queryJobInfo(@PathVariable Integer jobId) { + return jobService.queryJobInfo(jobId); + } + + @Operation(summary = "定时任务-分页查询 @huke") + @PostMapping("/job/query") + public ResponseDTO> queryJob(@RequestBody @Valid SmartJobQueryForm queryForm) { + return jobService.queryJob(queryForm); + } + + @Operation(summary = "定时任务-添加任务 @huke") + @PostMapping("/job/add") + @RepeatSubmit + public ResponseDTO addJob(@RequestBody @Valid SmartJobAddForm addForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + addForm.setUpdateName(requestUser.getUserName()); + return jobService.addJob(addForm); + } + + @Operation(summary = "定时任务-更新-任务信息 @huke") + @PostMapping("/job/update") + @RepeatSubmit + public ResponseDTO updateJob(@RequestBody @Valid SmartJobUpdateForm updateForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + updateForm.setUpdateName(requestUser.getUserName()); + return jobService.updateJob(updateForm); + } + + @Operation(summary = "定时任务-更新-开启状态 @huke") + @PostMapping("/job/update/enabled") + @RepeatSubmit + public ResponseDTO updateJobEnabled(@RequestBody @Valid SmartJobEnabledUpdateForm updateForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + updateForm.setUpdateName(requestUser.getUserName()); + return jobService.updateJobEnabled(updateForm); + } + + @Operation(summary = "定时任务-删除 @zhuoda") + @GetMapping("/job/delete") + @RepeatSubmit + public ResponseDTO deleteJob(@RequestParam Integer jobId) { + return jobService.deleteJob(jobId, SmartRequestUtil.getRequestUser()); + } + + @Operation(summary = "定时任务-执行记录-分页查询 @huke") + @PostMapping("/job/log/query") + public ResponseDTO> queryJobLog(@RequestBody @Valid SmartJobLogQueryForm queryForm) { + return jobService.queryJobLog(queryForm); + } +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/util/AdminRequestUtil.java b/yun-admin/src/main/java/net/lab1024/sa/admin/util/AdminRequestUtil.java new file mode 100644 index 0000000..caf4850 --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/util/AdminRequestUtil.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.util; + +import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.util.SmartRequestUtil; + +/** + * admin 端的请求工具类 + */ +public final class AdminRequestUtil { + + + public static RequestEmployee getRequestUser() { + return (RequestEmployee) SmartRequestUtil.getRequestUser(); + } + + public static Long getRequestUserId() { + RequestUser requestUser = getRequestUser(); + return null == requestUser ? null : requestUser.getUserId(); + } + + +} diff --git a/yun-admin/src/main/resources/dev/application.yaml b/yun-admin/src/main/resources/dev/application.yaml new file mode 100644 index 0000000..fa29f06 --- /dev/null +++ b/yun-admin/src/main/resources/dev/application.yaml @@ -0,0 +1,22 @@ +############################################################################################################# +# # +# 为了减少重复配置,本配置文件为此yun-admin的独有配置,更多配置请查看 yun-base 项目中的 yun-base.yaml 通用配置文件。 # +# 其中此文件中配置可以覆盖 yun-base.yaml 中的通用配置,具体实现类请看类:YamlProcessor.java # +# # +############################################################################################################# + +# 项目配置: 名称、日志目录 +project: + name: yun-admin + log-directory: ${localPath:/home}/logs/smart_admin_v3/${project.name}/${spring.profiles.active} + +# 项目端口和url根路径 +server: + port: 1024 + servlet: + context-path: / + +# 环境 +spring: + profiles: + active: '@profiles.active@' \ No newline at end of file diff --git a/yun-admin/src/main/resources/dev/log4j2-spring.xml b/yun-admin/src/main/resources/dev/log4j2-spring.xml new file mode 100644 index 0000000..cab3506 --- /dev/null +++ b/yun-admin/src/main/resources/dev/log4j2-spring.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/dev/spy.properties b/yun-admin/src/main/resources/dev/spy.properties new file mode 100644 index 0000000..667e1ea --- /dev/null +++ b/yun-admin/src/main/resources/dev/spy.properties @@ -0,0 +1,18 @@ +#相关的包 +modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory +# 日志格式 +logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger +#日志输出到控制台 +appender=com.p6spy.engine.spy.appender.StdoutLogger +# 设置 p6spy driver 代理 +deregisterdrivers=true +# 取消JDBC URL前缀 +useprefix=true +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. +excludecategories=info,debug,result,commit,resultset +# 日期格式 +dateformat=yyyy-MM-dd HH:mm:ss +# 开启慢sql +outagedetection=true +# 慢SQL记录标准(单位秒) +outagedetectioninterval=2 \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/category/CategoryMapper.xml b/yun-admin/src/main/resources/mapper/business/category/CategoryMapper.xml new file mode 100644 index 0000000..908509c --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/category/CategoryMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml b/yun-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml new file mode 100644 index 0000000..aeef387 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml @@ -0,0 +1,39 @@ + + + + + update t_goods + set deleted_flag = #{deletedFlag} + WHERE goods_id IN + + #{item} + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml b/yun-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml new file mode 100644 index 0000000..c742cc7 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml @@ -0,0 +1,58 @@ + + + + + UPDATE t_oa_bank + SET deleted_flag = #{deletedFlag} + WHERE bank_id = #{bankId} + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml b/yun-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml new file mode 100644 index 0000000..ba1a417 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml @@ -0,0 +1,94 @@ + + + + + + delete from t_oa_enterprise_employee where enterprise_id = #{enterpriseId} and employee_id in + + #{item} + + + + + delete from t_oa_enterprise_employee where employee_id = #{employeeId} + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml b/yun-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml new file mode 100644 index 0000000..1484e71 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml @@ -0,0 +1,89 @@ + + + + + UPDATE t_oa_enterprise + SET deleted_flag = #{deletedFlag} + WHERE enterprise_id = #{enterpriseId} + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml b/yun-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml new file mode 100644 index 0000000..afbc046 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml @@ -0,0 +1,56 @@ + + + + + UPDATE t_oa_invoice + SET deleted_flag = #{deletedFlag} + WHERE invoice_id = #{invoiceId} + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/business/oa/notice/NoticeMapper.xml b/yun-admin/src/main/resources/mapper/business/oa/notice/NoticeMapper.xml new file mode 100644 index 0000000..7e47a59 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/business/oa/notice/NoticeMapper.xml @@ -0,0 +1,275 @@ + + + + + + + t_notice.notice_id, + t_notice.notice_type_id, + t_notice.title, + t_notice.all_visible_flag, + t_notice.scheduled_publish_flag, + t_notice.publish_time, + t_notice.content_text, + t_notice.content_html, + t_notice.attachment, + t_notice.page_view_count, + t_notice.user_view_count, + t_notice.source, + t_notice.author, + t_notice.document_number, + t_notice.deleted_flag, + t_notice.create_user_id, + t_notice.update_time, + t_notice.create_time + + + + + + insert into t_notice_visible_range + (notice_id, data_type, data_id) + values + + ( #{noticeId} , #{item.dataType}, #{item.dataId} ) + + + + delete + from t_notice_visible_range + where notice_id = #{noticeId} + + + + + + + update t_notice + set deleted_flag = true + where notice_id = #{noticeId} + + + + + + + + + + + + + + + insert into t_notice_view_record (notice_id, employee_id, first_ip, first_user_agent, page_view_count) + values (#{noticeId}, #{employeeId}, #{ip}, #{userAgent}, #{pageViewCount}) + + + update t_notice_view_record + set page_view_count = page_view_count + 1, + last_ip = #{ip}, + last_user_agent = #{userAgent} + where notice_id = #{noticeId} + and employee_id = #{employeeId} + + + update t_notice + set page_view_count = page_view_count + #{pageViewCountIncrement}, + user_view_count = user_view_count + #{userViewCountIncrement} + where notice_id = #{noticeId} + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/letter/LetterMapper.xml b/yun-admin/src/main/resources/mapper/letter/LetterMapper.xml new file mode 100644 index 0000000..d5ecde8 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/letter/LetterMapper.xml @@ -0,0 +1,24 @@ + + + + + + + t_letter.letter_id, + t_letter.sort, + t_letter.disabled_flag, + t_letter.deleted_flag, + t_letter.user_id, + t_letter.update_time, + t_letter.create_time + + + + + + + diff --git a/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml b/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml new file mode 100644 index 0000000..75605c4 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml @@ -0,0 +1,106 @@ + + + + + + + t_service_applications.application_id, + t_service_applications.user_id, + t_service_applications.firm_id, + t_service_applications.service_start, + t_service_applications.service_end, + t_service_applications.service_duration, + t_service_applications.beneficiary_count, + t_service_applications.organizer_name, + t_service_applications.organizer_contact, + t_service_applications.organizer_phone, + t_service_applications.service_content, + t_service_applications.workload_score, + t_service_applications.firm_audit_status, + t_service_applications.firm_audit_opinion, + t_service_applications.firm_audit_user, + t_service_applications.firm_audit_time, + t_service_applications.association_audit_status, + t_service_applications.association_audit_opinion, + t_service_applications.association_audit_user, + t_service_applications.association_audit_time, + t_service_applications.record_no, + t_service_applications.record_status, + t_service_applications.record_time, + t_service_applications.update_time, + t_service_applications.create_time, + t_service_applications.deleted_flag, + t_service_applications.certificate_number, + t_service_applications.activity_category_id, + t_service_applications.activity_name_id, + t_service_applications.attachment_ids + + + + + + + update t_service_applications set deleted_flag = #{deletedFlag} + where application_id in + + #{item} + + + + + update t_service_applications set deleted_flag = #{deletedFlag} + where application_id = #{applicationId} + + + update t_service_applications set firm_audit_status = #{deletedFlag} + where application_id in + + #{item} + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/PositionMapper.xml b/yun-admin/src/main/resources/mapper/system/PositionMapper.xml new file mode 100644 index 0000000..bdc93ea --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/PositionMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml b/yun-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml new file mode 100644 index 0000000..939008a --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml b/yun-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml new file mode 100644 index 0000000..236a4e4 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + UPDATE t_employee + SET disabled_flag = #{disabledFlag} + WHERE employee_id = #{employeeId} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE t_employee + SET login_pwd = #{password} + WHERE employee_id = #{employeeId} + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/menu/MenuMapper.xml b/yun-admin/src/main/resources/mapper/system/menu/MenuMapper.xml new file mode 100644 index 0000000..68fbede --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/menu/MenuMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + update t_menu + set deleted_flag = #{deletedFlag}, + update_user_id = #{updateUserId} + where menu_id = #{item} + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml b/yun-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml new file mode 100644 index 0000000..b9f5bcf --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + DELETE FROM t_role_data_scope + WHERE role_id = #{roleId} + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml b/yun-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml new file mode 100644 index 0000000..390a19c --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE + FROM t_role_employee + WHERE employee_id = #{employeeId} + + + + + DELETE + FROM t_role_employee + WHERE role_id = #{roleId} + + + + DELETE + FROM t_role_employee + WHERE role_id = #{roleId} + and employee_id = #{employeeId} + + + + + DELETE FROM t_role_employee + WHERE role_id = #{roleId} and employee_id in + + #{item} + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/role/RoleMapper.xml b/yun-admin/src/main/resources/mapper/system/role/RoleMapper.xml new file mode 100644 index 0000000..884bdb7 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/role/RoleMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml b/yun-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml new file mode 100644 index 0000000..448fa58 --- /dev/null +++ b/yun-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml @@ -0,0 +1,39 @@ + + + + + delete + from t_role_menu + where role_id = #{roleId} + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/pre/application.yaml b/yun-admin/src/main/resources/pre/application.yaml new file mode 100644 index 0000000..327888b --- /dev/null +++ b/yun-admin/src/main/resources/pre/application.yaml @@ -0,0 +1,22 @@ +############################################################################################################# +# # +# 为了减少重复配置,本配置文件为此yun-admin的独有配置,更多配置请查看 yun-base 项目中的 yun-base.yaml 通用配置文件。 # +# 其中此文件中配置可以覆盖 yun-base.yaml 中的通用配置,具体实现类请看类:YamlProcessor.java # +# # +############################################################################################################# + +# 项目配置: 名称、日志目录 +project: + name: yun-admin + log-directory: /home/logs/smart_admin_v3/${project.name}/${spring.profiles.active} + +# 项目端口和url根路径 +server: + port: 1024 + servlet: + context-path: / + +# 环境 +spring: + profiles: + active: '@profiles.active@' \ No newline at end of file diff --git a/yun-admin/src/main/resources/pre/log4j2-spring.xml b/yun-admin/src/main/resources/pre/log4j2-spring.xml new file mode 100644 index 0000000..10fcc1c --- /dev/null +++ b/yun-admin/src/main/resources/pre/log4j2-spring.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/prod/application.yaml b/yun-admin/src/main/resources/prod/application.yaml new file mode 100644 index 0000000..327888b --- /dev/null +++ b/yun-admin/src/main/resources/prod/application.yaml @@ -0,0 +1,22 @@ +############################################################################################################# +# # +# 为了减少重复配置,本配置文件为此yun-admin的独有配置,更多配置请查看 yun-base 项目中的 yun-base.yaml 通用配置文件。 # +# 其中此文件中配置可以覆盖 yun-base.yaml 中的通用配置,具体实现类请看类:YamlProcessor.java # +# # +############################################################################################################# + +# 项目配置: 名称、日志目录 +project: + name: yun-admin + log-directory: /home/logs/smart_admin_v3/${project.name}/${spring.profiles.active} + +# 项目端口和url根路径 +server: + port: 1024 + servlet: + context-path: / + +# 环境 +spring: + profiles: + active: '@profiles.active@' \ No newline at end of file diff --git a/yun-admin/src/main/resources/prod/log4j2-spring.xml b/yun-admin/src/main/resources/prod/log4j2-spring.xml new file mode 100644 index 0000000..822d276 --- /dev/null +++ b/yun-admin/src/main/resources/prod/log4j2-spring.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/test/application.yaml b/yun-admin/src/main/resources/test/application.yaml new file mode 100644 index 0000000..9591fdd --- /dev/null +++ b/yun-admin/src/main/resources/test/application.yaml @@ -0,0 +1,22 @@ +############################################################################################################# +# # +# 为了减少重复配置,本配置文件为此yun-admin的独有配置,更多配置请查看 yun-base 项目中的 yun-base.yaml 通用配置文件。 # +# 其中此文件中配置可以覆盖 yun-base.yaml 中的通用配置,具体实现类请看类:YamlProcessor.java # +# # +############################################################################################################# + +# 项目配置: 名称、日志目录 +project: + name: yun-admin + log-directory: /home/project/smartadmin/test/log + +# 项目端口和url根路径 +server: + port: 11024 + servlet: + context-path: / + +# 环境 +spring: + profiles: + active: '@profiles.active@' \ No newline at end of file diff --git a/yun-admin/src/main/resources/test/log4j2-spring.xml b/yun-admin/src/main/resources/test/log4j2-spring.xml new file mode 100644 index 0000000..10fcc1c --- /dev/null +++ b/yun-admin/src/main/resources/test/log4j2-spring.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/src/main/resources/test/spy.properties b/yun-admin/src/main/resources/test/spy.properties new file mode 100644 index 0000000..667e1ea --- /dev/null +++ b/yun-admin/src/main/resources/test/spy.properties @@ -0,0 +1,18 @@ +#相关的包 +modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory +# 日志格式 +logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger +#日志输出到控制台 +appender=com.p6spy.engine.spy.appender.StdoutLogger +# 设置 p6spy driver 代理 +deregisterdrivers=true +# 取消JDBC URL前缀 +useprefix=true +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. +excludecategories=info,debug,result,commit,resultset +# 日期格式 +dateformat=yyyy-MM-dd HH:mm:ss +# 开启慢sql +outagedetection=true +# 慢SQL记录标准(单位秒) +outagedetectioninterval=2 \ No newline at end of file diff --git a/yun-admin/src/test/java/net/lab1024/sa/admin/AdminApplicationTest.java b/yun-admin/src/test/java/net/lab1024/sa/admin/AdminApplicationTest.java new file mode 100644 index 0000000..0d8d423 --- /dev/null +++ b/yun-admin/src/test/java/net/lab1024/sa/admin/AdminApplicationTest.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class AdminApplicationTest { + + @BeforeEach + public void before() { + System.out.println("----------------------- 测试开始 -----------------------"); + + } + + @AfterEach + public void after() { + System.out.println("----------------------- 测试结束 -----------------------"); + } + +} + diff --git a/yun-admin/target/classes/application.yaml b/yun-admin/target/classes/application.yaml new file mode 100644 index 0000000..5583c1e --- /dev/null +++ b/yun-admin/target/classes/application.yaml @@ -0,0 +1,22 @@ +############################################################################################################# +# # +# 为了减少重复配置,本配置文件为此yun-admin的独有配置,更多配置请查看 yun-base 项目中的 yun-base.yaml 通用配置文件。 # +# 其中此文件中配置可以覆盖 yun-base.yaml 中的通用配置,具体实现类请看类:YamlProcessor.java # +# # +############################################################################################################# + +# 项目配置: 名称、日志目录 +project: + name: yun-admin + log-directory: ${localPath:/home}/logs/smart_admin_v3/yun-admin/${spring.profiles.active} + +# 项目端口和url根路径 +server: + port: 1024 + servlet: + context-path: / + +# 环境 +spring: + profiles: + active: 'dev' \ No newline at end of file diff --git a/yun-admin/target/classes/log4j2-spring.xml b/yun-admin/target/classes/log4j2-spring.xml new file mode 100644 index 0000000..cab3506 --- /dev/null +++ b/yun-admin/target/classes/log4j2-spring.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/category/CategoryMapper.xml b/yun-admin/target/classes/mapper/business/category/CategoryMapper.xml new file mode 100644 index 0000000..908509c --- /dev/null +++ b/yun-admin/target/classes/mapper/business/category/CategoryMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/goods/GoodsMapper.xml b/yun-admin/target/classes/mapper/business/goods/GoodsMapper.xml new file mode 100644 index 0000000..aeef387 --- /dev/null +++ b/yun-admin/target/classes/mapper/business/goods/GoodsMapper.xml @@ -0,0 +1,39 @@ + + + + + update t_goods + set deleted_flag = #{deletedFlag} + WHERE goods_id IN + + #{item} + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/oa/bank/BankMapper.xml b/yun-admin/target/classes/mapper/business/oa/bank/BankMapper.xml new file mode 100644 index 0000000..c742cc7 --- /dev/null +++ b/yun-admin/target/classes/mapper/business/oa/bank/BankMapper.xml @@ -0,0 +1,58 @@ + + + + + UPDATE t_oa_bank + SET deleted_flag = #{deletedFlag} + WHERE bank_id = #{bankId} + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml b/yun-admin/target/classes/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml new file mode 100644 index 0000000..ba1a417 --- /dev/null +++ b/yun-admin/target/classes/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml @@ -0,0 +1,94 @@ + + + + + + delete from t_oa_enterprise_employee where enterprise_id = #{enterpriseId} and employee_id in + + #{item} + + + + + delete from t_oa_enterprise_employee where employee_id = #{employeeId} + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/oa/enterprise/EnterpriseMapper.xml b/yun-admin/target/classes/mapper/business/oa/enterprise/EnterpriseMapper.xml new file mode 100644 index 0000000..1484e71 --- /dev/null +++ b/yun-admin/target/classes/mapper/business/oa/enterprise/EnterpriseMapper.xml @@ -0,0 +1,89 @@ + + + + + UPDATE t_oa_enterprise + SET deleted_flag = #{deletedFlag} + WHERE enterprise_id = #{enterpriseId} + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/oa/invoice/InvoiceMapper.xml b/yun-admin/target/classes/mapper/business/oa/invoice/InvoiceMapper.xml new file mode 100644 index 0000000..afbc046 --- /dev/null +++ b/yun-admin/target/classes/mapper/business/oa/invoice/InvoiceMapper.xml @@ -0,0 +1,56 @@ + + + + + UPDATE t_oa_invoice + SET deleted_flag = #{deletedFlag} + WHERE invoice_id = #{invoiceId} + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/business/oa/notice/NoticeMapper.xml b/yun-admin/target/classes/mapper/business/oa/notice/NoticeMapper.xml new file mode 100644 index 0000000..7e47a59 --- /dev/null +++ b/yun-admin/target/classes/mapper/business/oa/notice/NoticeMapper.xml @@ -0,0 +1,275 @@ + + + + + + + t_notice.notice_id, + t_notice.notice_type_id, + t_notice.title, + t_notice.all_visible_flag, + t_notice.scheduled_publish_flag, + t_notice.publish_time, + t_notice.content_text, + t_notice.content_html, + t_notice.attachment, + t_notice.page_view_count, + t_notice.user_view_count, + t_notice.source, + t_notice.author, + t_notice.document_number, + t_notice.deleted_flag, + t_notice.create_user_id, + t_notice.update_time, + t_notice.create_time + + + + + + insert into t_notice_visible_range + (notice_id, data_type, data_id) + values + + ( #{noticeId} , #{item.dataType}, #{item.dataId} ) + + + + delete + from t_notice_visible_range + where notice_id = #{noticeId} + + + + + + + update t_notice + set deleted_flag = true + where notice_id = #{noticeId} + + + + + + + + + + + + + + + insert into t_notice_view_record (notice_id, employee_id, first_ip, first_user_agent, page_view_count) + values (#{noticeId}, #{employeeId}, #{ip}, #{userAgent}, #{pageViewCount}) + + + update t_notice_view_record + set page_view_count = page_view_count + 1, + last_ip = #{ip}, + last_user_agent = #{userAgent} + where notice_id = #{noticeId} + and employee_id = #{employeeId} + + + update t_notice + set page_view_count = page_view_count + #{pageViewCountIncrement}, + user_view_count = user_view_count + #{userViewCountIncrement} + where notice_id = #{noticeId} + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/letter/LetterMapper.xml b/yun-admin/target/classes/mapper/letter/LetterMapper.xml new file mode 100644 index 0000000..d5ecde8 --- /dev/null +++ b/yun-admin/target/classes/mapper/letter/LetterMapper.xml @@ -0,0 +1,24 @@ + + + + + + + t_letter.letter_id, + t_letter.sort, + t_letter.disabled_flag, + t_letter.deleted_flag, + t_letter.user_id, + t_letter.update_time, + t_letter.create_time + + + + + + + diff --git a/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml b/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml new file mode 100644 index 0000000..75605c4 --- /dev/null +++ b/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml @@ -0,0 +1,106 @@ + + + + + + + t_service_applications.application_id, + t_service_applications.user_id, + t_service_applications.firm_id, + t_service_applications.service_start, + t_service_applications.service_end, + t_service_applications.service_duration, + t_service_applications.beneficiary_count, + t_service_applications.organizer_name, + t_service_applications.organizer_contact, + t_service_applications.organizer_phone, + t_service_applications.service_content, + t_service_applications.workload_score, + t_service_applications.firm_audit_status, + t_service_applications.firm_audit_opinion, + t_service_applications.firm_audit_user, + t_service_applications.firm_audit_time, + t_service_applications.association_audit_status, + t_service_applications.association_audit_opinion, + t_service_applications.association_audit_user, + t_service_applications.association_audit_time, + t_service_applications.record_no, + t_service_applications.record_status, + t_service_applications.record_time, + t_service_applications.update_time, + t_service_applications.create_time, + t_service_applications.deleted_flag, + t_service_applications.certificate_number, + t_service_applications.activity_category_id, + t_service_applications.activity_name_id, + t_service_applications.attachment_ids + + + + + + + update t_service_applications set deleted_flag = #{deletedFlag} + where application_id in + + #{item} + + + + + update t_service_applications set deleted_flag = #{deletedFlag} + where application_id = #{applicationId} + + + update t_service_applications set firm_audit_status = #{deletedFlag} + where application_id in + + #{item} + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/PositionMapper.xml b/yun-admin/target/classes/mapper/system/PositionMapper.xml new file mode 100644 index 0000000..bdc93ea --- /dev/null +++ b/yun-admin/target/classes/mapper/system/PositionMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/department/DepartmentMapper.xml b/yun-admin/target/classes/mapper/system/department/DepartmentMapper.xml new file mode 100644 index 0000000..939008a --- /dev/null +++ b/yun-admin/target/classes/mapper/system/department/DepartmentMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/employee/EmployeeMapper.xml b/yun-admin/target/classes/mapper/system/employee/EmployeeMapper.xml new file mode 100644 index 0000000..236a4e4 --- /dev/null +++ b/yun-admin/target/classes/mapper/system/employee/EmployeeMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + UPDATE t_employee + SET disabled_flag = #{disabledFlag} + WHERE employee_id = #{employeeId} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE t_employee + SET login_pwd = #{password} + WHERE employee_id = #{employeeId} + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/menu/MenuMapper.xml b/yun-admin/target/classes/mapper/system/menu/MenuMapper.xml new file mode 100644 index 0000000..68fbede --- /dev/null +++ b/yun-admin/target/classes/mapper/system/menu/MenuMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + update t_menu + set deleted_flag = #{deletedFlag}, + update_user_id = #{updateUserId} + where menu_id = #{item} + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/role/RoleDataScopeMapper.xml b/yun-admin/target/classes/mapper/system/role/RoleDataScopeMapper.xml new file mode 100644 index 0000000..b9f5bcf --- /dev/null +++ b/yun-admin/target/classes/mapper/system/role/RoleDataScopeMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + DELETE FROM t_role_data_scope + WHERE role_id = #{roleId} + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/role/RoleEmployeeMapper.xml b/yun-admin/target/classes/mapper/system/role/RoleEmployeeMapper.xml new file mode 100644 index 0000000..390a19c --- /dev/null +++ b/yun-admin/target/classes/mapper/system/role/RoleEmployeeMapper.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE + FROM t_role_employee + WHERE employee_id = #{employeeId} + + + + + DELETE + FROM t_role_employee + WHERE role_id = #{roleId} + + + + DELETE + FROM t_role_employee + WHERE role_id = #{roleId} + and employee_id = #{employeeId} + + + + + DELETE FROM t_role_employee + WHERE role_id = #{roleId} and employee_id in + + #{item} + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/role/RoleMapper.xml b/yun-admin/target/classes/mapper/system/role/RoleMapper.xml new file mode 100644 index 0000000..884bdb7 --- /dev/null +++ b/yun-admin/target/classes/mapper/system/role/RoleMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/mapper/system/role/RoleMenuMapper.xml b/yun-admin/target/classes/mapper/system/role/RoleMenuMapper.xml new file mode 100644 index 0000000..448fa58 --- /dev/null +++ b/yun-admin/target/classes/mapper/system/role/RoleMenuMapper.xml @@ -0,0 +1,39 @@ + + + + + delete + from t_role_menu + where role_id = #{roleId} + + + + + + \ No newline at end of file diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/AdminApplication.class b/yun-admin/target/classes/net/lab1024/sa/admin/AdminApplication.class new file mode 100644 index 0000000..d53e2da Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/AdminApplication.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/common/enums/ReviewEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/common/enums/ReviewEnum.class new file mode 100644 index 0000000..27f8369 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/common/enums/ReviewEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/config/MvcConfig.class b/yun-admin/target/classes/net/lab1024/sa/admin/config/MvcConfig.class new file mode 100644 index 0000000..4cf5af8 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/config/MvcConfig.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/config/OperateLogAspectConfig.class b/yun-admin/target/classes/net/lab1024/sa/admin/config/OperateLogAspectConfig.class new file mode 100644 index 0000000..41cde1a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/config/OperateLogAspectConfig.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Category.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Category.class new file mode 100644 index 0000000..577df92 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Category.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Department.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Department.class new file mode 100644 index 0000000..9b88b0f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Department.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Login.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Login.class new file mode 100644 index 0000000..4a3cb46 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst$Login.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst.class new file mode 100644 index 0000000..dc666a7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminCacheConst.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminRedisKeyConst.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminRedisKeyConst.class new file mode 100644 index 0000000..76e50ca Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminRedisKeyConst.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst$Business.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst$Business.class new file mode 100644 index 0000000..ad51da7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst$Business.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst$System.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst$System.class new file mode 100644 index 0000000..8fde33c Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst$System.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.class b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.class new file mode 100644 index 0000000..75de7c5 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/interceptor/AdminInterceptor.class b/yun-admin/target/classes/net/lab1024/sa/admin/interceptor/AdminInterceptor.class new file mode 100644 index 0000000..dda2aa4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/interceptor/AdminInterceptor.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.class new file mode 100644 index 0000000..7538651 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/controller/CategoryController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/controller/CategoryController.class new file mode 100644 index 0000000..47b9a8b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/controller/CategoryController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.class new file mode 100644 index 0000000..f20285e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.class new file mode 100644 index 0000000..c578dc8 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.class new file mode 100644 index 0000000..e4e8042 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.class new file mode 100644 index 0000000..8708e6c Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.class new file mode 100644 index 0000000..efb61f5 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.class new file mode 100644 index 0000000..101809d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.class new file mode 100644 index 0000000..363b673 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.class new file mode 100644 index 0000000..aa5407f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.class new file mode 100644 index 0000000..ade89c3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.class new file mode 100644 index 0000000..46f954f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.class new file mode 100644 index 0000000..e33372e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/service/CategoryService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/service/CategoryService.class new file mode 100644 index 0000000..ac7167a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/category/service/CategoryService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.class new file mode 100644 index 0000000..b4ccab4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.class new file mode 100644 index 0000000..6d9d9de Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.class new file mode 100644 index 0000000..0d7e9b7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.class new file mode 100644 index 0000000..54ed7f2 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.class new file mode 100644 index 0000000..030ef3b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.class new file mode 100644 index 0000000..ff11b8d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.class new file mode 100644 index 0000000..4acb850 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.class new file mode 100644 index 0000000..44474ed Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO$GoodsExcelVOBuilder.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO$GoodsExcelVOBuilder.class new file mode 100644 index 0000000..1285ca8 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO$GoodsExcelVOBuilder.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.class new file mode 100644 index 0000000..ac6e0eb Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.class new file mode 100644 index 0000000..f359685 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/service/GoodsService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/service/GoodsService.class new file mode 100644 index 0000000..b4c5bf9 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/goods/service/GoodsService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/controller/BankController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/controller/BankController.class new file mode 100644 index 0000000..0aed26f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/controller/BankController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/dao/BankDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/dao/BankDao.class new file mode 100644 index 0000000..3192fb0 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/dao/BankDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.class new file mode 100644 index 0000000..b6e25f9 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.class new file mode 100644 index 0000000..cec016e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.class new file mode 100644 index 0000000..ebff187 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.class new file mode 100644 index 0000000..d9ecca4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.class new file mode 100644 index 0000000..0d3e96c Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/service/BankService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/service/BankService.class new file mode 100644 index 0000000..ff382c7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/bank/service/BankService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.class new file mode 100644 index 0000000..0052bb1 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/controller/EnterpriseController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/controller/EnterpriseController.class new file mode 100644 index 0000000..1d67229 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/controller/EnterpriseController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.class new file mode 100644 index 0000000..9a69ca4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.class new file mode 100644 index 0000000..b6020a3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.class new file mode 100644 index 0000000..4a6d8ce Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.class new file mode 100644 index 0000000..75cd073 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.class new file mode 100644 index 0000000..9ccc79c Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.class new file mode 100644 index 0000000..835b50f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.class new file mode 100644 index 0000000..78d6218 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.class new file mode 100644 index 0000000..2d8ad37 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.class new file mode 100644 index 0000000..f3ce807 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.class new file mode 100644 index 0000000..9fbbf3b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.class new file mode 100644 index 0000000..a00cd06 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.class new file mode 100644 index 0000000..467bbda Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.class new file mode 100644 index 0000000..2eeb0c3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/manager/EnterpriseEmployeeManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/manager/EnterpriseEmployeeManager.class new file mode 100644 index 0000000..f32b0b6 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/manager/EnterpriseEmployeeManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/service/EnterpriseService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/service/EnterpriseService.class new file mode 100644 index 0000000..205ab21 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/enterprise/service/EnterpriseService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/controller/InvoiceController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/controller/InvoiceController.class new file mode 100644 index 0000000..a13c819 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/controller/InvoiceController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/dao/InvoiceDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/dao/InvoiceDao.class new file mode 100644 index 0000000..992175a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/dao/InvoiceDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.class new file mode 100644 index 0000000..7906d32 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.class new file mode 100644 index 0000000..5d7bec1 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.class new file mode 100644 index 0000000..547c632 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.class new file mode 100644 index 0000000..7622c23 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.class new file mode 100644 index 0000000..fda6df0 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/service/InvoiceService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/service/InvoiceService.class new file mode 100644 index 0000000..7486e0a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/invoice/service/InvoiceService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.class new file mode 100644 index 0000000..fe8e20a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.class new file mode 100644 index 0000000..3be6080 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.class new file mode 100644 index 0000000..a21c9ea Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.class new file mode 100644 index 0000000..e44feea Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.class new file mode 100644 index 0000000..30cbca3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity$NoticeTypeEntityBuilder.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity$NoticeTypeEntityBuilder.class new file mode 100644 index 0000000..b418dec Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity$NoticeTypeEntityBuilder.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.class new file mode 100644 index 0000000..87d5017 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.class new file mode 100644 index 0000000..6330331 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.class new file mode 100644 index 0000000..15baa31 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.class new file mode 100644 index 0000000..f535f02 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.class new file mode 100644 index 0000000..2fee94e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.class new file mode 100644 index 0000000..3be7a29 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.class new file mode 100644 index 0000000..d743f55 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.class new file mode 100644 index 0000000..3d0d997 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.class new file mode 100644 index 0000000..4e50b7a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.class new file mode 100644 index 0000000..76fae0c Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.class new file mode 100644 index 0000000..9be1a36 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.class new file mode 100644 index 0000000..2f10178 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.class new file mode 100644 index 0000000..7007948 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.class new file mode 100644 index 0000000..e36ba4d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.class new file mode 100644 index 0000000..5a98ea4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.class new file mode 100644 index 0000000..c1b7f48 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.class new file mode 100644 index 0000000..9eeb71f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.class new file mode 100644 index 0000000..a40b156 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/controller/LetterController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/controller/LetterController.class new file mode 100644 index 0000000..820172b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/controller/LetterController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/dao/LetterDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/dao/LetterDao.class new file mode 100644 index 0000000..96f57dc Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/dao/LetterDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/entity/LetterEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/entity/LetterEntity.class new file mode 100644 index 0000000..b356213 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/entity/LetterEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/form/LetterQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/form/LetterQueryForm.class new file mode 100644 index 0000000..982e0da Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/form/LetterQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/vo/LetterVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/vo/LetterVO.class new file mode 100644 index 0000000..4a2a16d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/domain/vo/LetterVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/manager/LetterManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/manager/LetterManager.class new file mode 100644 index 0000000..bc6667b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/manager/LetterManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/service/LetterService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/service/LetterService.class new file mode 100644 index 0000000..27c475d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/service/LetterService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/sql/LetterMenu.sql b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/sql/LetterMenu.sql new file mode 100644 index 0000000..80ec17a --- /dev/null +++ b/yun-admin/target/classes/net/lab1024/sa/admin/module/letter/sql/LetterMenu.sql @@ -0,0 +1,22 @@ +# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下, +# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。 +# 如果你一切都是按照默认,那么下面的 SQL 基本不用改 + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id ) +VALUES ( '承诺书签订表', 2, 0, '/letter/list', '/business/letter/letter-list.vue', false, false, true, false, 1, 1 ); + +# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID +SET @parent_id = NULL; +SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '承诺书签订表'; + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '查询', 3, @parent_id, false, false, true, false, 1, 'letter:query', 'letter:query', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '添加', 3, @parent_id, false, false, true, false, 1, 'letter:add', 'letter:add', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '更新', 3, @parent_id, false, false, true, false, 1, 'letter:update', 'letter:update', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '删除', 3, @parent_id, false, false, true, false, 1, 'letter:delete', 'letter:delete', @parent_id, 1 ); diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class new file mode 100644 index 0000000..9b109b3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class new file mode 100644 index 0000000..3906705 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class new file mode 100644 index 0000000..5b5817b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsAddForm.class new file mode 100644 index 0000000..a9b5a3d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsImportForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsImportForm.class new file mode 100644 index 0000000..1f4c560 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsImportForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsQueryForm.class new file mode 100644 index 0000000..8a7d136 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsUpdateForm.class new file mode 100644 index 0000000..f0ce26d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/form/ServiceApplicationsUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ActivityCategoryConverter.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ActivityCategoryConverter.class new file mode 100644 index 0000000..5c338ef Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ActivityCategoryConverter.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ActivityNameConverter.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ActivityNameConverter.class new file mode 100644 index 0000000..b3f8366 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ActivityNameConverter.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/EmployeeNameConverter.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/EmployeeNameConverter.class new file mode 100644 index 0000000..04c11c4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/EmployeeNameConverter.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/OrganizationNameConverter.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/OrganizationNameConverter.class new file mode 100644 index 0000000..54d59d3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/OrganizationNameConverter.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsTemplateVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsTemplateVO.class new file mode 100644 index 0000000..d632cc8 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsTemplateVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsVO.class new file mode 100644 index 0000000..a7a8ad9 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/vo/ServiceApplicationsVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/manager/ServiceApplicationsManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/manager/ServiceApplicationsManager.class new file mode 100644 index 0000000..268247d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/manager/ServiceApplicationsManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsDataListener.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsDataListener.class new file mode 100644 index 0000000..6e2cfec Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsDataListener.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class new file mode 100644 index 0000000..cd01b58 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class new file mode 100644 index 0000000..ba6ee03 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/DataScope.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/DataScope.class new file mode 100644 index 0000000..1c43497 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/DataScope.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin$BoundSqlSqlSource.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin$BoundSqlSqlSource.class new file mode 100644 index 0000000..8864517 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin$BoundSqlSqlSource.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.class new file mode 100644 index 0000000..364d483 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.class new file mode 100644 index 0000000..9c8b473 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.class new file mode 100644 index 0000000..ac6891d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.class new file mode 100644 index 0000000..b16dccd Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/controller/DataScopeController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/controller/DataScopeController.class new file mode 100644 index 0000000..1e21abc Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/controller/DataScopeController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.class new file mode 100644 index 0000000..814c020 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO$DataScopeDTOBuilder.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO$DataScopeDTOBuilder.class new file mode 100644 index 0000000..96e2664 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO$DataScopeDTOBuilder.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.class new file mode 100644 index 0000000..58e37ac Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.class new file mode 100644 index 0000000..8b55a9f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO$DataScopeViewTypeVOBuilder.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO$DataScopeViewTypeVOBuilder.class new file mode 100644 index 0000000..1abd6a7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO$DataScopeViewTypeVOBuilder.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.class new file mode 100644 index 0000000..02bfd3e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.class new file mode 100644 index 0000000..4b4e015 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.class new file mode 100644 index 0000000..3212e2f Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.class new file mode 100644 index 0000000..ec7c394 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/strategy/AbstractDataScopeStrategy.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/strategy/AbstractDataScopeStrategy.class new file mode 100644 index 0000000..162bb86 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/datascope/strategy/AbstractDataScopeStrategy.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.class new file mode 100644 index 0000000..0f4062d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.class new file mode 100644 index 0000000..fd1c699 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.class new file mode 100644 index 0000000..1bddefd Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.class new file mode 100644 index 0000000..d2de4cb Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.class new file mode 100644 index 0000000..6473db5 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.class new file mode 100644 index 0000000..f66d661 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.class new file mode 100644 index 0000000..846c1ce Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.class new file mode 100644 index 0000000..c4d64d4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.class new file mode 100644 index 0000000..315b6bc Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/service/DepartmentService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/service/DepartmentService.class new file mode 100644 index 0000000..6b18507 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/department/service/DepartmentService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.class new file mode 100644 index 0000000..36d4758 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.class new file mode 100644 index 0000000..40f3009 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.class new file mode 100644 index 0000000..6a6dd99 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.class new file mode 100644 index 0000000..bec650b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.class new file mode 100644 index 0000000..2ae465b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.class new file mode 100644 index 0000000..e51680e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateAvatarForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateAvatarForm.class new file mode 100644 index 0000000..0e0c8d1 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateAvatarForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateCenterForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateCenterForm.class new file mode 100644 index 0000000..472acd4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateCenterForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.class new file mode 100644 index 0000000..a7dd530 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.class new file mode 100644 index 0000000..c5c7cb1 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.class new file mode 100644 index 0000000..071c841 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.class new file mode 100644 index 0000000..512490e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.class new file mode 100644 index 0000000..a54f216 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.class new file mode 100644 index 0000000..93b9d73 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/controller/LoginController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/controller/LoginController.class new file mode 100644 index 0000000..4045727 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/controller/LoginController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/LoginForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/LoginForm.class new file mode 100644 index 0000000..6fbbffb Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/LoginForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/LoginResultVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/LoginResultVO.class new file mode 100644 index 0000000..45dbe8a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/LoginResultVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/RequestEmployee.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/RequestEmployee.class new file mode 100644 index 0000000..a344f73 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/domain/RequestEmployee.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/manager/LoginManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/manager/LoginManager.class new file mode 100644 index 0000000..0aa5c02 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/manager/LoginManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/service/LoginService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/service/LoginService.class new file mode 100644 index 0000000..ecfb10e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/login/service/LoginService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.class new file mode 100644 index 0000000..6ddeca3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.class new file mode 100644 index 0000000..45d537e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/controller/MenuController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/controller/MenuController.class new file mode 100644 index 0000000..8e5f15e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/controller/MenuController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.class new file mode 100644 index 0000000..6a4039a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.class new file mode 100644 index 0000000..eeab321 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.class new file mode 100644 index 0000000..49c7b5e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.class new file mode 100644 index 0000000..76871dd Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.class new file mode 100644 index 0000000..9c5f1d2 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.class new file mode 100644 index 0000000..9714025 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.class new file mode 100644 index 0000000..115205d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.class new file mode 100644 index 0000000..f056b89 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.class new file mode 100644 index 0000000..c36d2d7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/service/MenuService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/service/MenuService.class new file mode 100644 index 0000000..0cd7c04 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/menu/service/MenuService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/message/AdminMessageController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/message/AdminMessageController.class new file mode 100644 index 0000000..77759a3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/message/AdminMessageController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/controller/PositionController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/controller/PositionController.class new file mode 100644 index 0000000..5a946fe Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/controller/PositionController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/dao/PositionDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/dao/PositionDao.class new file mode 100644 index 0000000..93ba117 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/dao/PositionDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/entity/PositionEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/entity/PositionEntity.class new file mode 100644 index 0000000..37ad8cb Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/entity/PositionEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionAddForm.class new file mode 100644 index 0000000..722d840 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionQueryForm.class new file mode 100644 index 0000000..9142f4e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionUpdateForm.class new file mode 100644 index 0000000..4f77361 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/form/PositionUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/vo/PositionVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/vo/PositionVO.class new file mode 100644 index 0000000..f4c15b3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/domain/vo/PositionVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/manager/PositionManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/manager/PositionManager.class new file mode 100644 index 0000000..16adb78 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/manager/PositionManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/service/PositionService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/service/PositionService.class new file mode 100644 index 0000000..78a622b Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/position/service/PositionService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleController.class new file mode 100644 index 0000000..a88fd4d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.class new file mode 100644 index 0000000..5d50861 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.class new file mode 100644 index 0000000..fefeef1 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.class new file mode 100644 index 0000000..ff57c8e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleDao.class new file mode 100644 index 0000000..90be696 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.class new file mode 100644 index 0000000..ace4712 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.class new file mode 100644 index 0000000..0f33c9e Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.class new file mode 100644 index 0000000..b2d95b7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.class new file mode 100644 index 0000000..70c2335 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.class new file mode 100644 index 0000000..a88d346 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.class new file mode 100644 index 0000000..1d15160 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.class new file mode 100644 index 0000000..a2bce69 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.class new file mode 100644 index 0000000..706fd14 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm$RoleUpdateDataScopeListFormItem.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm$RoleUpdateDataScopeListFormItem.class new file mode 100644 index 0000000..659fe56 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm$RoleUpdateDataScopeListFormItem.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.class new file mode 100644 index 0000000..c601298 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.class new file mode 100644 index 0000000..8a98900 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.class new file mode 100644 index 0000000..e832900 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.class new file mode 100644 index 0000000..4f28279 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.class new file mode 100644 index 0000000..3bdbfc4 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.class new file mode 100644 index 0000000..7c32050 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.class new file mode 100644 index 0000000..59d9b96 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.class new file mode 100644 index 0000000..6d62b0d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.class new file mode 100644 index 0000000..3708ea9 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.class new file mode 100644 index 0000000..cb4b394 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.class new file mode 100644 index 0000000..ad7da90 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.class new file mode 100644 index 0000000..f59d74a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.class new file mode 100644 index 0000000..6beb7d9 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.class new file mode 100644 index 0000000..5ac24b2 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.class new file mode 100644 index 0000000..86e4814 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.class new file mode 100644 index 0000000..654a710 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.class new file mode 100644 index 0000000..a074ac3 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleService.class new file mode 100644 index 0000000..17fb7ee Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/role/service/RoleService.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController$JweForm.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController$JweForm.class new file mode 100644 index 0000000..24e97c2 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController$JweForm.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController.class new file mode 100644 index 0000000..c6596a8 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminApiEncryptController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminCacheController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminCacheController.class new file mode 100644 index 0000000..e2d16e9 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminCacheController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.class new file mode 100644 index 0000000..1fcce0d Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminConfigController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminConfigController.class new file mode 100644 index 0000000..0297c25 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminConfigController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController$DataVO.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController$DataVO.class new file mode 100644 index 0000000..86c0213 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController$DataVO.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController.class new file mode 100644 index 0000000..44f5f13 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDataMaskingDemoController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDictController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDictController.class new file mode 100644 index 0000000..c5250c1 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminDictController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminFileController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminFileController.class new file mode 100644 index 0000000..7a4b36a Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminFileController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.class new file mode 100644 index 0000000..4e96c49 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.class new file mode 100644 index 0000000..d1105d0 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.class new file mode 100644 index 0000000..40c3706 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.class new file mode 100644 index 0000000..607ea28 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminProtectController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminProtectController.class new file mode 100644 index 0000000..f1b8766 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminProtectController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminReloadController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminReloadController.class new file mode 100644 index 0000000..67d9076 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminReloadController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.class new file mode 100644 index 0000000..87e61f7 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminSmartJobController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminSmartJobController.class new file mode 100644 index 0000000..dbc6963 Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/module/system/support/AdminSmartJobController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/util/AdminRequestUtil.class b/yun-admin/target/classes/net/lab1024/sa/admin/util/AdminRequestUtil.class new file mode 100644 index 0000000..beb3e5c Binary files /dev/null and b/yun-admin/target/classes/net/lab1024/sa/admin/util/AdminRequestUtil.class differ diff --git a/yun-admin/target/classes/spy.properties b/yun-admin/target/classes/spy.properties new file mode 100644 index 0000000..667e1ea --- /dev/null +++ b/yun-admin/target/classes/spy.properties @@ -0,0 +1,18 @@ +#相关的包 +modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory +# 日志格式 +logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger +#日志输出到控制台 +appender=com.p6spy.engine.spy.appender.StdoutLogger +# 设置 p6spy driver 代理 +deregisterdrivers=true +# 取消JDBC URL前缀 +useprefix=true +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. +excludecategories=info,debug,result,commit,resultset +# 日期格式 +dateformat=yyyy-MM-dd HH:mm:ss +# 开启慢sql +outagedetection=true +# 慢SQL记录标准(单位秒) +outagedetectioninterval=2 \ No newline at end of file diff --git a/yun-admin/target/test-classes/net/lab1024/sa/admin/AdminApplicationTest.class b/yun-admin/target/test-classes/net/lab1024/sa/admin/AdminApplicationTest.class new file mode 100644 index 0000000..62e0919 Binary files /dev/null and b/yun-admin/target/test-classes/net/lab1024/sa/admin/AdminApplicationTest.class differ diff --git a/yun-base/pom.xml b/yun-base/pom.xml new file mode 100644 index 0000000..7153695 --- /dev/null +++ b/yun-base/pom.xml @@ -0,0 +1,311 @@ + + 4.0.0 + + net.lab1024 + yun-parent + 3.0.0 + ../pom.xml + + + yun-base + 3.0.0 + + yun-base + yun-base project + + + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-logging + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + cn.dev33 + sa-token-spring-boot-starter + + + + cn.dev33 + sa-token-redis-jackson + + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.apache.logging.log4j + log4j-spring-boot + + + + org.apache.logging.log4j + log4j-web + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-test + + + + org.springframework.security + spring-security-crypto + + + + com.mysql + mysql-connector-j + + + + com.github.ben-manes.caffeine + caffeine + + + error_prone_annotations + com.google.errorprone + + + + + + org.projectlombok + lombok + + + + org.apache.commons + commons-pool2 + + + + org.apache.commons + commons-text + + + + org.springframework + spring-mock + + + + com.baomidou + mybatis-plus-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + + + + + com.baomidou + mybatis-plus-jsqlparser-4.9 + + + + p6spy + p6spy + + + + org.springdoc + springdoc-openapi-ui + + + + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter + + + + com.squareup.okhttp3 + okhttp + + + + com.alibaba + fastjson + + + + com.alibaba + druid + + + + com.google.guava + guava + + + + com.googlecode.concurrentlinkedhashmap + concurrentlinkedhashmap-lru + + + + org.reflections + reflections + + + + software.amazon.awssdk + s3 + + + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-collections4 + + + + commons-io + commons-io + + + + org.apache.commons + commons-compress + + + + cn.hutool + hutool-all + + + + org.apache.velocity + velocity-engine-core + + + + org.apache.velocity.tools + velocity-tools-generic + + + + org.lionsoul + ip2region + + + + org.bouncycastle + bcprov-jdk18on + + + + cn.idev.excel + fastexcel + + + + org.apache.poi + poi + + + + org.apache.poi + poi-ooxml + + + + org.apache.poi + poi-scratchpad + + + + org.apache.poi + poi-ooxml-full + + + + net.1024lab + smartdb + ${smartdb.version} + + + + org.redisson + redisson-spring-boot-starter + + + org.redisson + redisson-spring-data-27 + + + + org.yaml + snakeyaml + + + + org.springframework.boot + spring-boot-starter-mail + + + + org.jsoup + jsoup + + + + org.freemarker + freemarker + + + + org.apache.tika + tika-core + ${tika.version} + + + + + + diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/annoation/NoNeedLogin.java b/yun-base/src/main/java/net/lab1024/sa/base/common/annoation/NoNeedLogin.java new file mode 100644 index 0000000..87e10e1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/annoation/NoNeedLogin.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.common.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 不需要登录注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface NoNeedLogin { +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCode.java b/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCode.java new file mode 100644 index 0000000..e5b4eae --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCode.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.base.common.code; + +/** + * 错误码
+ * 一共分为三种: 1)系统错误、2)用户级别错误、3)未预期到的错误 + */ +public interface ErrorCode { + + /** + * 系统等级 + */ + String LEVEL_SYSTEM = "system"; + + /** + * 用户等级 + */ + String LEVEL_USER = "user"; + + /** + * 未预期到的等级 + */ + String LEVEL_UNEXPECTED = "unexpected"; + + /** + * 错误码 + */ + int getCode(); + + /** + * 错误消息 + * + */ + String getMsg(); + + /** + * 错误等级 + */ + String getLevel(); + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCodeRangeContainer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCodeRangeContainer.java new file mode 100644 index 0000000..73c5b3a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCodeRangeContainer.java @@ -0,0 +1,111 @@ +package net.lab1024.sa.base.common.code; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 错误码 注册容器 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/27 22:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +class ErrorCodeRangeContainer { + + /** + * 所有的错误码均大于10000 + */ + static final int MIN_START_CODE = 10000; + + static final Map, ImmutablePair> CODE_RANGE_MAP = new ConcurrentHashMap<>(); + + /** + * 用于统计数量 + */ + static int errorCounter = 0; + + /** + * 注册状态码 + * 校验是否重复 是否越界 + * + */ + static void register(Class clazz, int start, int end) { + String simpleName = clazz.getSimpleName(); + if (!clazz.isEnum()) { + throw new ExceptionInInitializerError(String.format("<> error: %s not Enum class !", simpleName)); + } + if (start > end) { + throw new ExceptionInInitializerError(String.format("<> error: %s start must be less than the end !", simpleName)); + } + + if (start <= MIN_START_CODE) { + throw new ExceptionInInitializerError(String.format("<> error: %s start must be more than %s !", simpleName, MIN_START_CODE)); + } + + // 校验是否重复注册 + boolean containsKey = CODE_RANGE_MAP.containsKey(clazz); + if (containsKey) { + throw new ExceptionInInitializerError(String.format("<> error: Enum %s already exist !", simpleName)); + } + + // 校验 开始结束值 是否越界 + CODE_RANGE_MAP.forEach((k, v) -> { + if (isExistOtherRange(start, end, v)) { + throw new IllegalArgumentException(String.format("<> error: %s[%d,%d] has intersection with class:%s[%d,%d]", simpleName, start, end, + k.getSimpleName(), v.getLeft(), v.getRight())); + } + }); + + // 循环校验code并存储 + List codeList = Stream.of(clazz.getEnumConstants()).map(codeEnum -> { + int code = codeEnum.getCode(); + if (code < start || code > end) { + throw new IllegalArgumentException(String.format("<> error: %s[%d,%d] code %d out of range", simpleName, start, end, code)); + } + return code; + }).collect(Collectors.toList()); + + // 校验code是否重复 + List distinctCodeList = codeList.stream().distinct().collect(Collectors.toList()); + Collection subtract = CollectionUtils.subtract(codeList, distinctCodeList); + if (CollectionUtils.isNotEmpty(subtract)) { + throw new IllegalArgumentException(String.format("<> error: %s code %s is repeat!", simpleName, subtract)); + } + + CODE_RANGE_MAP.put(clazz, ImmutablePair.of(start, end)); + // 统计 + errorCounter = errorCounter + distinctCodeList.size(); + } + + /** + * 是否存在于其他范围 + */ + private static boolean isExistOtherRange(int start, int end, ImmutablePair range) { + if (start >= range.getLeft() && start <= range.getRight()) { + return true; + } + + if (end >= range.getLeft() && end <= range.getRight()) { + return true; + } + + return false; + } + + /** + * 进行初始化 + */ + static int initialize() { + return errorCounter; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCodeRegister.java b/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCodeRegister.java new file mode 100644 index 0000000..4fa925a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/code/ErrorCodeRegister.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.base.common.code; + +import static net.lab1024.sa.base.common.code.ErrorCodeRangeContainer.register; + +/** + * 注册code状态码
+ * ps:为什么要在此处不那么优雅的手动注册? + * 主要是为了能统一、清晰、浏览当前定义的所有状态码 + * 方便后续维护 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/27 23:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class ErrorCodeRegister { + + static { + + // 系统 错误码 + register(SystemErrorCode.class, 10001, 20000); + + // 意外 错误码 + register(UnexpectedErrorCode.class, 20001, 30000); + + // 用户 通用错误码 + register(UserErrorCode.class, 30001, 40000); + + } + + + public static int initialize() { + return ErrorCodeRangeContainer.initialize(); + } + + public static void main(String[] args) { + ErrorCodeRegister.initialize(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/code/SystemErrorCode.java b/yun-base/src/main/java/net/lab1024/sa/base/common/code/SystemErrorCode.java new file mode 100644 index 0000000..f3e0c39 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/code/SystemErrorCode.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 系统错误状态码(此类返回码应该高度重视) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/10/24 20:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Getter +@AllArgsConstructor +public enum SystemErrorCode implements ErrorCode { + + /** + * 系统错误 + */ + SYSTEM_ERROR(10001, "系统似乎出现了点小问题"), + + ; + + private final int code; + + private final String msg; + + private final String level; + + SystemErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_SYSTEM; + } + +} + diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/code/UnexpectedErrorCode.java b/yun-base/src/main/java/net/lab1024/sa/base/common/code/UnexpectedErrorCode.java new file mode 100644 index 0000000..c1517e7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/code/UnexpectedErrorCode.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 未预期的错误码(即发生了不可能发生的事情,此类返回码应该高度重视) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/27 22:10:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Getter +@AllArgsConstructor +public enum UnexpectedErrorCode implements ErrorCode { + + /** + * 业务错误 + */ + BUSINESS_HANDING(20001, "呃~ 业务繁忙,请稍后重试"), + + /** + * id错误 + */ + PAY_ORDER_ID_ERROR(20002, "付款单id发生了异常,请联系技术人员排查"), + + ; + + private final int code; + + private final String msg; + + private final String level; + + UnexpectedErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_UNEXPECTED; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/code/UserErrorCode.java b/yun-base/src/main/java/net/lab1024/sa/base/common/code/UserErrorCode.java new file mode 100644 index 0000000..f6dcfeb --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/code/UserErrorCode.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.base.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 用户级别的错误码(用户引起的错误返回码,可以不用关注) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/21 22:12:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Getter +@AllArgsConstructor +public enum UserErrorCode implements ErrorCode { + + PARAM_ERROR(30001, "参数错误"), + + DATA_NOT_EXIST(30002, "左翻右翻,数据竟然找不到了~"), + + ALREADY_EXIST(30003, "数据已存在了呀~"), + + REPEAT_SUBMIT(30004, "亲~您操作的太快了,请稍等下再操作~"), + + NO_PERMISSION(30005, "对不起,您没有权限访问此内容哦~"), + + DEVELOPING(30006, "系統正在紧急开发中,敬请期待~"), + + LOGIN_STATE_INVALID(30007, "您还未登录或登录失效,请重新登录!"), + + USER_STATUS_ERROR(30008, "用户状态异常"), + + FORM_REPEAT_SUBMIT(30009, "请勿重复提交"), + + LOGIN_FAIL_LOCK(30010, "登录连续失败已经被锁定,无法登录"), + LOGIN_FAIL_WILL_LOCK(30011, "登录连续失败将会锁定提醒"), + + LOGIN_ACTIVE_TIMEOUT(30012, "长时间未操作系统,需要重新登录"); + + private final int code; + + private final String msg; + + private final String level; + + UserErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_USER; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/constant/RequestHeaderConst.java b/yun-base/src/main/java/net/lab1024/sa/base/common/constant/RequestHeaderConst.java new file mode 100644 index 0000000..d0e4060 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/constant/RequestHeaderConst.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.base.common.constant; + +/** + * 请求消息头常量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-15 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class RequestHeaderConst { + + public static final String TOKEN = "Authorization"; + + public static final String USER_AGENT = "user-agent"; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/constant/StringConst.java b/yun-base/src/main/java/net/lab1024/sa/base/common/constant/StringConst.java new file mode 100644 index 0000000..e9e8fdf --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/constant/StringConst.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.common.constant; + +/** + * 字符串常量 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-10-14 23:16:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class StringConst { + + /** + * 全局通用分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 全局通用分隔符 下划线 + */ + public static final String UNDERLINE = "_"; + + /** + * 全局通用 横杠 + */ + public static final String HORIZONTAL = "-"; + + /** + * 全局通用分隔符 + */ + public static final Character SEPARATOR_CHAR = ','; + + /** + * 全局通用分隔符 斜杠 + */ + public static final String SEPARATOR_SLASH = "/"; + + /** + * 空字符串 + */ + public static final String EMPTY = ""; + + /** + * 全局通用 冒号 + */ + public static final String COLON = ":"; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/controller/SupportBaseController.java b/yun-base/src/main/java/net/lab1024/sa/base/common/controller/SupportBaseController.java new file mode 100644 index 0000000..6f0a28d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/controller/SupportBaseController.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.base.common.controller; + +import net.lab1024.sa.base.constant.SwaggerTagConst; +import org.springframework.web.bind.annotation.RequestMapping; + + +/** + * 支撑类业务路由基类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-04-24 20:43:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RequestMapping(SwaggerTagConst.Support.URL_PREFIX) +public class SupportBaseController { +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/DataScopePlugin.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/DataScopePlugin.java new file mode 100644 index 0000000..0fe704c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/DataScopePlugin.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.base.common.domain; + +import org.apache.ibatis.plugin.Interceptor; + +/** + * 数据范围 插件 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-11-15 17:20:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public abstract class DataScopePlugin implements Interceptor { +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/PageParam.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/PageParam.java new file mode 100644 index 0000000..24c13df --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/PageParam.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.common.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 分页基础参数 + */ +@Data +public class PageParam { + + @Schema(description = "页码(不能为空)", example = "1") + @NotNull(message = "分页参数不能为空") + private Long pageNum; + + @Schema(description = "每页数量(不能为空)", example = "10") + @NotNull(message = "每页数量不能为空") + @Max(value = 500, message = "每页最大为500") + private Long pageSize; + + @Schema(description = "是否查询总条数") + protected Boolean searchCount; + + @Schema(description = "排序字段集合") + @Size(max = 10, message = "排序字段最多10") + @Valid + private List sortItemList; + + /** + * 排序DTO类 + */ + @Data + public static class SortItem { + + @Schema(description = "true正序|false倒序") + @NotNull(message = "排序规则不能为空") + private Boolean isAsc; + + @Schema(description = "排序字段") + @NotBlank(message = "排序字段不能为空") + @Length(max = 30, message = "排序字段最多30") + private String column; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/PageResult.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/PageResult.java new file mode 100644 index 0000000..d499174 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/PageResult.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.base.common.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 分页返回对象 + */ +@Data +public class PageResult { + + /** + * 当前页 + */ + @Schema(description = "当前页") + private Long pageNum; + + /** + * 每页的数量 + */ + @Schema(description = "每页的数量") + private Long pageSize; + + /** + * 总记录数 + */ + @Schema(description = "总记录数") + private Long total; + + /** + * 总页数 + */ + @Schema(description = "总页数") + private Long pages; + + /** + * 结果集 + */ + @Schema(description = "结果集") + private List list; + + @Schema(description = "是否为空") + private Boolean emptyFlag; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/RequestUrlVO.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/RequestUrlVO.java new file mode 100644 index 0000000..4669c2d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/RequestUrlVO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.base.common.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 请求url返回对象 + * + * @Author 1024创新实验室: 李善逸 + * @Date 2021/9/1 20:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class RequestUrlVO { + + @Schema(description = "注释说明") + private String comment; + + @Schema(description = "controller.method") + private String name; + + @Schema(description = "url") + private String url; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/RequestUser.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/RequestUser.java new file mode 100644 index 0000000..d88f608 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/RequestUser.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.common.domain; + +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; + +/** + * 请求用户 + */ +public interface RequestUser { + + /** + * 请求用户id + * + * @return + */ + Long getUserId(); + + /** + * 请求用户名称 + * + * @return + */ + String getUserName(); + + /** + * 获取用户类型 + */ + UserTypeEnum getUserType(); + + /** + * 获取请求的IP + * + * @return + */ + String getIp(); + + /** + * 获取请求 user-agent + * + * @return + */ + String getUserAgent(); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ResponseDTO.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ResponseDTO.java new file mode 100644 index 0000000..a34a9e6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ResponseDTO.java @@ -0,0 +1,115 @@ +package net.lab1024.sa.base.common.domain; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.code.ErrorCode; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.enumeration.DataTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import org.apache.commons.lang3.StringUtils; + +/** + * 请求返回对象 + */ +@Data +@Schema +public class ResponseDTO { + + public static final int OK_CODE = 0; + + public static final String OK_MSG = "操作成功"; + + @Schema(description = "返回码") + private Integer code; + + @Schema(description = "级别") + private String level; + + private String msg; + + private Boolean ok; + + @Schema(description = "返回数据") + private T data; + + @SchemaEnum(value = DataTypeEnum.class,desc = "数据类型") + private Integer dataType; + + public ResponseDTO(Integer code, String level, boolean ok, String msg, T data) { + this.code = code; + this.level = level; + this.ok = ok; + this.msg = msg; + this.data = data; + this.dataType = DataTypeEnum.NORMAL.getValue(); + } + + public ResponseDTO(Integer code, String level, boolean ok, String msg) { + this.code = code; + this.level = level; + this.ok = ok; + this.msg = msg; + this.dataType = DataTypeEnum.NORMAL.getValue(); + } + + public ResponseDTO(ErrorCode errorCode, boolean ok, String msg, T data) { + this.code = errorCode.getCode(); + this.level = errorCode.getLevel(); + this.ok = ok; + if (StringUtils.isNotBlank(msg)) { + this.msg = msg; + } else { + this.msg = errorCode.getMsg(); + } + this.data = data; + this.dataType = DataTypeEnum.NORMAL.getValue(); + } + + public static ResponseDTO ok() { + return new ResponseDTO<>(OK_CODE, null, true, OK_MSG, null); + } + + public static ResponseDTO ok(T data) { + return new ResponseDTO<>(OK_CODE, null, true, OK_MSG, data); + } + + public static ResponseDTO okMsg(String msg) { + return new ResponseDTO<>(OK_CODE, null, true, msg, null); + } + + // -------------------------------------------- 最常用的 用户参数 错误码 -------------------------------------------- + + public static ResponseDTO userErrorParam() { + return new ResponseDTO<>(UserErrorCode.PARAM_ERROR, false, null, null); + } + + + public static ResponseDTO userErrorParam(String msg) { + return new ResponseDTO<>(UserErrorCode.PARAM_ERROR, false, msg, null); + } + + // -------------------------------------------- 错误码 -------------------------------------------- + + public static ResponseDTO error(ErrorCode errorCode) { + return new ResponseDTO<>(errorCode, false, null, null); + } + + public static ResponseDTO error(ErrorCode errorCode, boolean ok) { + return new ResponseDTO<>(errorCode, ok, null, null); + } + + public static ResponseDTO error(ResponseDTO responseDTO) { + return new ResponseDTO<>(responseDTO.getCode(), responseDTO.getLevel(), responseDTO.getOk(), responseDTO.getMsg(), null); + } + + public static ResponseDTO error(ErrorCode errorCode, String msg) { + return new ResponseDTO<>(errorCode, false, msg, null); + } + + public static ResponseDTO errorData(ErrorCode errorCode, T data) { + return new ResponseDTO<>(errorCode, false, null, data); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/SystemEnvironment.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/SystemEnvironment.java new file mode 100644 index 0000000..232b292 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/SystemEnvironment.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.base.common.domain; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.SystemEnvironmentEnum; + +/** + * 系统环境 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/8/13 21:06:11 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public class SystemEnvironment { + + /** + * 是否位生产环境 + */ + private boolean isProd; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 当前环境 + */ + private SystemEnvironmentEnum currentEnvironment; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/UserPermission.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/UserPermission.java new file mode 100644 index 0000000..355b948 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/UserPermission.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.common.domain; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * sa-token 所需的权限信息 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/8/26 15:23:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Data +public class UserPermission implements Serializable { + + /** + * 权限列表 + */ + private List permissionList; + + /** + * 角色列表 + */ + private List roleList; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ValidateData.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ValidateData.java new file mode 100644 index 0000000..dee1f8c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ValidateData.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.base.common.domain; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 校验数据是否为空的包装类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2020/10/16 21:06:11 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ValidateData { + + @NotNull(message = "数据不能为空哦") + private T data; +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ValidateList.java b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ValidateList.java new file mode 100644 index 0000000..188e3f4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/domain/ValidateList.java @@ -0,0 +1,153 @@ +package net.lab1024.sa.base.common.domain; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import java.util.*; + +/** + * 校验集合是否为空的包装类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-02-03 17:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class ValidateList implements List { + + @Valid + @NotEmpty(message = "数据长度不能为空哦") + private List list; + + public ValidateList() { + this.list = new ArrayList<>(); + } + + public ValidateList(List list) { + this.list = list; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + @Override + public int size() { + return list.size(); + } + + @Override + public boolean isEmpty() { + return list.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return list.contains(o); + } + + @Override + public Iterator iterator() { + return list.iterator(); + } + + @Override + public Object[] toArray() { + return list.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return list.toArray(a); + } + + @Override + public boolean add(E e) { + return list.add(e); + } + + @Override + public boolean remove(Object o) { + return list.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return list.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return list.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + return list.addAll(index, c); + } + + @Override + public boolean removeAll(Collection c) { + return list.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return list.retainAll(c); + } + + @Override + public void clear() { + list.clear(); + } + + @Override + public E get(int index) { + return list.get(index); + } + + @Override + public E set(int index, E element) { + return list.set(index, element); + } + + @Override + public void add(int index, E element) { + list.add(index, element); + } + + @Override + public E remove(int index) { + return list.remove(index); + } + + @Override + public int indexOf(Object o) { + return list.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return list.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return list.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return list.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return list.subList(fromIndex, toIndex); + } + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/BaseEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/BaseEnum.java new file mode 100644 index 0000000..6593aa9 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/BaseEnum.java @@ -0,0 +1,99 @@ +package net.lab1024.sa.base.common.enumeration; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONAware; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.CaseFormat; +import lombok.Data; + +import java.util.LinkedHashMap; +import java.util.Objects; + +/** + * 枚举类接口 + * + * @Author 1024创新实验室: 胡克 + * @Date 2018-07-17 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public interface BaseEnum { + + /** + * 获取枚举类的值 + * + * @return + */ + Object getValue(); + + /** + * 获取枚举类的说明 + * + * @return String + */ + String getDesc(); + + /** + * 比较参数是否与枚举类的value相同 + * + * @param value + * @return boolean + */ + default boolean equalsValue(Object value) { + return Objects.equals(getValue(), value); + } + + /** + * 比较枚举类是否相同 + * + * @param baseEnum + * @return boolean + */ + default boolean equals(BaseEnum baseEnum) { + return Objects.equals(getValue(), baseEnum.getValue()) && Objects.equals(getDesc(), baseEnum.getDesc()); + } + + /** + * 返回枚举类的说明 + * + * @param clazz 枚举类类对象 + * @return + */ + static String getInfo(Class clazz) { + BaseEnum[] enums = clazz.getEnumConstants(); + LinkedHashMap json = new LinkedHashMap<>(enums.length); + for (BaseEnum e : enums) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("value", new DeletedQuotationAware(e.getValue())); + jsonObject.put("desc", new DeletedQuotationAware(e.getDesc())); + json.put(e.toString(), jsonObject); + } + + String enumJson = JSON.toJSONString(json, true); + enumJson = enumJson.replaceAll("\"", ""); + enumJson = enumJson.replaceAll("\t", "  "); + enumJson = enumJson.replaceAll("\n", "
"); + String prefix = "
export const " + CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, clazz.getSimpleName() + " =
"); + return prefix + enumJson + "
"; + } + + @Data + class DeletedQuotationAware implements JSONAware { + + private String value; + + public DeletedQuotationAware(Object value) { + if (value instanceof String) { + this.value = "'" + value + "'"; + } else { + this.value = value.toString(); + } + } + + @Override + public String toJSONString() { + return value; + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/DataTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/DataTypeEnum.java new file mode 100644 index 0000000..6cb068c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/DataTypeEnum.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.common.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/25 09:47:13 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Getter +@AllArgsConstructor +public enum DataTypeEnum implements BaseEnum { + + /** + *普通数据 + */ + NORMAL(1, "普通数据"), + + /** + * 加密数据 + */ + ENCRYPT(10, "加密数据"), + ; + private final Integer value; + + private final String desc; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/GenderEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/GenderEnum.java new file mode 100644 index 0000000..cbfbc39 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/GenderEnum.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.common.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 性别枚举类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019/09/24 16:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum GenderEnum implements BaseEnum { + + /** + * 0 未知 + */ + UNKNOWN(0, "未知"), + + /** + * 男 1 奇数为阳 + */ + MAN(1, "男"), + + /** + * 女 2 偶数为阴 + */ + WOMAN(2, "女"); + + private final Integer value; + + private final String desc; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum.java new file mode 100644 index 0000000..c4167fd --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.base.common.enumeration; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 系统环境枚举类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-10-15 22:45:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum SystemEnvironmentEnum implements BaseEnum { + /** + * dev + */ + DEV(SystemEnvironmentNameConst.DEV, "开发环境"), + + /** + * test + */ + TEST(SystemEnvironmentNameConst.TEST, "测试环境"), + + /** + * pre + */ + PRE(SystemEnvironmentNameConst.PRE, "预发布环境"), + + /** + * prod + */ + PROD(SystemEnvironmentNameConst.PROD, "生产环境"); + + private final String value; + + private final String desc; + + public static final class SystemEnvironmentNameConst { + public static final String DEV = "dev"; + public static final String TEST = "test"; + public static final String PRE = "pre"; + public static final String PROD = "prod"; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/UserTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/UserTypeEnum.java new file mode 100644 index 0000000..60bec4d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/enumeration/UserTypeEnum.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.common.enumeration; + +/** + * 用户类型 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/10/19 21:46:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum UserTypeEnum implements BaseEnum { + + /** + * 管理端 员工用户 + */ + ADMIN_EMPLOYEE(1, "员工"); + + private Integer type; + + private String desc; + + UserTypeEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + @Override + public Integer getValue() { + return type; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/exception/BusinessException.java b/yun-base/src/main/java/net/lab1024/sa/base/common/exception/BusinessException.java new file mode 100644 index 0000000..481210d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/exception/BusinessException.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.common.exception; + +import net.lab1024.sa.base.common.code.ErrorCode; + +/** + * 业务逻辑异常,全局异常拦截后统一返回ResponseCodeConst.SYSTEM_ERROR + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/25 21:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class BusinessException extends RuntimeException { + + public BusinessException() { + } + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMsg()); + } + + public BusinessException(String message) { + super(message); + } + + public BusinessException(String message, Throwable cause) { + super(message, cause); + } + + public BusinessException(Throwable cause) { + super(cause); + } + + public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/DictDataDeserializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/DictDataDeserializer.java new file mode 100644 index 0000000..3369045 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/DictDataDeserializer.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.common.json.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 字典反序列化 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-08-12 22:17:53 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class DictDataDeserializer extends JsonDeserializer { + + @Override + public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + List list = new ArrayList<>(); + ObjectCodec objectCodec = jsonParser.getCodec(); + JsonNode listOrObjectNode = objectCodec.readTree(jsonParser); + String deserialize = ""; + try { + if (listOrObjectNode.isArray()) { + for (JsonNode node : listOrObjectNode) { + list.add(node.asText()); + } + } else { + list.add(listOrObjectNode.asText()); + } + deserialize = String.join(",", list); + } catch (Exception e) { + log.error(e.getMessage(), e); + deserialize = listOrObjectNode.asText(); + } + return deserialize; + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/FileKeyVoDeserializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/FileKeyVoDeserializer.java new file mode 100644 index 0000000..f2ebab1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/FileKeyVoDeserializer.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.base.common.json.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 文件key反序列化
+ * 由于前端接收到的是序列化过的字段, 这边入库需要进行反序列化操作比较方便处理 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-11-24 17:15:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class FileKeyVoDeserializer extends JsonDeserializer { + + @Override + public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + List list = new ArrayList<>(); + ObjectCodec objectCodec = jsonParser.getCodec(); + JsonNode listOrObjectNode = objectCodec.readTree(jsonParser); + String deserialize = ""; + try { + if (listOrObjectNode.isArray()) { + for (JsonNode node : listOrObjectNode) { + list.add(objectCodec.treeToValue(node, FileVO.class)); + } + } else { + list.add(objectCodec.treeToValue(listOrObjectNode, FileVO.class)); + } + deserialize = list.stream().map(FileVO::getFileKey).collect(Collectors.joining(",")); + } catch (Exception e) { + log.error(e.getMessage(), e); + deserialize = listOrObjectNode.asText(); + } + return deserialize; + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/LongJsonDeserializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/LongJsonDeserializer.java new file mode 100644 index 0000000..01117eb --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/deserializer/LongJsonDeserializer.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.common.json.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; + +/** + * Long类型序列化 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-06-02 22:55:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class LongJsonDeserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String value = jsonParser.getText(); + try { + return value == null ? null : Long.parseLong(value); + } catch (NumberFormatException e) { + return null; + } + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/BigDecimalNullZeroSerializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/BigDecimalNullZeroSerializer.java new file mode 100644 index 0000000..aac0566 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/BigDecimalNullZeroSerializer.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.base.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.math.BigDecimal; + +/** + * 数字序列化 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/20 21:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class BigDecimalNullZeroSerializer extends JsonSerializer { + + @Override + public void serialize(BigDecimal value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (value == null) { + jsonGenerator.writeNumber(BigDecimal.ZERO); + return; + } + jsonGenerator.writeNumber(value); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/DataMaskingSerializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/DataMaskingSerializer.java new file mode 100644 index 0000000..ffe7c84 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/DataMaskingSerializer.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import net.lab1024.sa.base.module.support.datamasking.DataMasking; +import net.lab1024.sa.base.module.support.datamasking.DataMaskingTypeEnum; +import net.lab1024.sa.base.module.support.datamasking.SmartDataMaskingUtil; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.IOException; + +/** + * 脱敏序列化 + * + * @author 罗伊 + * @description: + * @date 2024/7/21 4:39 下午 + */ +public class DataMaskingSerializer extends JsonSerializer implements ContextualSerializer { + + private DataMaskingTypeEnum typeEnum; + + @Override + public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { + + if (ObjectUtils.isEmpty(value)) { + jsonGenerator.writeObject(value); + return; + } + + if (typeEnum == null) { + jsonGenerator.writeObject(SmartDataMaskingUtil.dataMasking(String.valueOf(value))); + return; + } + + jsonGenerator.writeObject(SmartDataMaskingUtil.dataMasking(value, typeEnum)); + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { + // 判断beanProperty是不是空 + if (null == property) { + return prov.findNullValueSerializer(property); + } + + DataMasking annotation = property.getAnnotation(DataMasking.class); + if (null == annotation) { + return prov.findValueSerializer(property.getType(), property); + } + + typeEnum = annotation.value(); + return this; + } + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/FileKeySerializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/FileKeySerializer.java new file mode 100644 index 0000000..7f5be30 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/FileKeySerializer.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.file.service.FileService; +import org.apache.commons.lang3.StringUtils; + +import javax.annotation.Resource; +import java.io.IOException; + +/** + * 文件key进行序列化对象 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/15 22:06 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class FileKeySerializer extends JsonSerializer { + + @Resource + private FileService fileService; + + + @Override + public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (StringUtils.isEmpty(value)) { + jsonGenerator.writeString(value); + return; + } + if (fileService == null) { + jsonGenerator.writeString(value); + return; + } + ResponseDTO responseDTO = fileService.getFileUrl(value); + if (responseDTO.getOk()) { + jsonGenerator.writeString(responseDTO.getData()); + return; + } + jsonGenerator.writeString(value); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/FileKeyVoSerializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/FileKeyVoSerializer.java new file mode 100644 index 0000000..707b732 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/FileKeyVoSerializer.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.google.common.collect.Lists; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.base.module.support.file.service.FileService; +import org.apache.commons.lang3.StringUtils; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * 文件key进行序列化对象 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/15 22:06 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class FileKeyVoSerializer extends JsonSerializer { + + @Resource + private FileService fileService; + + + @Override + public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (StringUtils.isEmpty(value)) { + jsonGenerator.writeObject(Lists.newArrayList()); + return; + } + if(fileService == null){ + jsonGenerator.writeString(value); + return; + } + String[] fileKeyArray = value.split(","); + List fileKeyList = Arrays.asList(fileKeyArray); + List fileKeyVOList = fileService.getFileList(fileKeyList); + jsonGenerator.writeObject(fileKeyVOList); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/LongJsonSerializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/LongJsonSerializer.java new file mode 100644 index 0000000..b83ec2f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/LongJsonSerializer.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * Long类型序列化 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-06-02 22:55:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class LongJsonSerializer extends JsonSerializer { + + public static final LongJsonSerializer INSTANCE = new LongJsonSerializer(); + + /** + * JS 安全整数范围 + * 根据 JS Number.MIN_SAFE_INTEGER 与 Number.MAX_SAFE_INTEGER 得来 + */ + private static final long JS_MIN_SAFE_INTEGER = -9007199254740991L; + private static final long JS_MAX_SAFE_INTEGER = 9007199254740991L; + + + @Override + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + if (null == value) { + gen.writeNull(); + return; + } + // 如果超出了 JavaScript 安全整数范围,则序列化为字符串 + if (value < JS_MIN_SAFE_INTEGER || value > JS_MAX_SAFE_INTEGER) { + gen.writeString(Long.toString(value)); + } else { + // 否则,序列化为数字 + gen.writeNumber(value); + } + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerialize.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerialize.java new file mode 100644 index 0000000..ace962b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerialize.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.base.common.json.serializer.enumeration; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 枚举类 序列化 注解 + * + * @author huke + * @date 2024年6月29日 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@JacksonAnnotationsInside +@JsonSerialize(using = EnumSerializer.class, nullsUsing = EnumSerializer.class) +public @interface EnumSerialize { + + Class value(); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerializer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerializer.java new file mode 100644 index 0000000..9cd2324 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerializer.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.base.common.json.serializer.enumeration; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.enumeration.BaseEnum; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; + +import java.io.IOException; +import java.util.stream.Collectors; + +/** + * 枚举 序列化 + * + * @author huke + * @date 2024年6月29日 + */ +public class EnumSerializer extends JsonSerializer implements ContextualSerializer { + + private Class enumClazz; + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeObject(value); + String fieldName = gen.getOutputContext().getCurrentName() + "Desc"; + Object desc; + // 多个枚举类 逗号分割 + if (value instanceof String && String.valueOf(value).contains(StringConst.SEPARATOR)) { + desc = SmartStringUtil.splitConvertToIntList(String.valueOf(value), StringConst.SEPARATOR) + .stream().map(e -> SmartEnumUtil.getEnumDescByValue(e, enumClazz)).collect(Collectors.toList()); + + } else { + BaseEnum anEnum = SmartEnumUtil.getEnumByValue(value, enumClazz); + desc = null != anEnum ? anEnum.getDesc() : null; + } + gen.writeObjectField(fieldName, desc); + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { + EnumSerialize annotation = property.getAnnotation(EnumSerialize.class); + if (null == annotation) { + return prov.findValueSerializer(property.getType(), property); + } + enumClazz = annotation.value(); + return this; + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SchemaEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SchemaEnum.java new file mode 100644 index 0000000..b0a9421 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SchemaEnum.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.common.swagger; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 枚举类字段属性的 自定义 swagger 注解 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019/05/16 23:18 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface SchemaEnum { + + /** + * 枚举类对象 + * + */ + Class value(); + + String example() default ""; + + boolean hidden() default false; + + boolean required() default true; + + String dataType() default ""; + + String desc() default ""; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SchemaEnumPropertyCustomizer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SchemaEnumPropertyCustomizer.java new file mode 100644 index 0000000..d487b0e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SchemaEnumPropertyCustomizer.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.common.swagger; + +import io.swagger.v3.core.converter.AnnotatedType; +import io.swagger.v3.oas.models.media.Schema; +import net.lab1024.sa.base.common.enumeration.BaseEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import org.springdoc.core.customizers.PropertyCustomizer; +import org.springframework.stereotype.Component; + +import java.lang.annotation.Annotation; + +/** + * + * 自定义枚举类文档 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/12/25 23:28:51 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Component +public class SchemaEnumPropertyCustomizer implements PropertyCustomizer { + + @Override + public Schema customize(Schema schema, AnnotatedType type) { + if (type.getCtxAnnotations() == null) { + return schema; + } + + StringBuilder description = new StringBuilder(); + for (Annotation ctxAnnotation : type.getCtxAnnotations()) { + if (ctxAnnotation.annotationType().equals(CheckEnum.class) && ((CheckEnum) ctxAnnotation).required()) { + description.append("【必填】"); + } + } + + for (Annotation ctxAnnotation : type.getCtxAnnotations()) { + if (ctxAnnotation.annotationType().equals(SchemaEnum.class)) { + description.append(((SchemaEnum) ctxAnnotation).desc()); + Class clazz = ((SchemaEnum) ctxAnnotation).value(); + description.append(BaseEnum.getInfo(clazz)); + } + } + + if (description.length() > 0) { + schema.setDescription(description.toString()); + } + return schema; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SmartOperationCustomizer.java b/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SmartOperationCustomizer.java new file mode 100644 index 0000000..041182d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/swagger/SmartOperationCustomizer.java @@ -0,0 +1,114 @@ +package net.lab1024.sa.base.common.swagger; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaCheckRole; +import cn.dev33.satoken.annotation.SaMode; +import io.swagger.v3.oas.models.Operation; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiDecrypt; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiEncrypt; +import org.springdoc.core.customizers.OperationCustomizer; +import org.springframework.web.method.HandlerMethod; + +import java.util.ArrayList; +import java.util.List; + +/** + * 权限、接口加解密等 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/12/26 13:47:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class SmartOperationCustomizer implements OperationCustomizer { + + @Override + public Operation customize(Operation operation, HandlerMethod handlerMethod) { + + List noteList = new ArrayList<>(); + + // 请求参数加密 + List encryptBuilderList = new ArrayList<>(); + + if (handlerMethod.getMethodAnnotation(ApiDecrypt.class) != null || + handlerMethod.getBeanType().getAnnotation(ApiDecrypt.class) != null) { + encryptBuilderList.add("【请求参数加密】"); + } + + if (handlerMethod.getMethodAnnotation(ApiEncrypt.class) != null || + handlerMethod.getBeanType().getAnnotation(ApiEncrypt.class) != null) { + encryptBuilderList.add("【返回结果加密】"); + } + + if (!encryptBuilderList.isEmpty()) { + noteList.add("
接口安全:" + SmartStringUtil.join(",", encryptBuilderList) + ""); + } + + // 权限 + noteList.addAll(getPermission(handlerMethod)); + + // 更新 + operation.setDescription(SmartStringUtil.join("
", noteList)); + + return operation; + } + + + private List getPermission(HandlerMethod handlerMethod) { + List values = new ArrayList<>(); + + StringBuilder permissionStringBuilder = new StringBuilder(); + SaCheckPermission classPermissions = handlerMethod.getBeanType().getAnnotation(SaCheckPermission.class); + if (classPermissions != null) { + permissionStringBuilder.append(""); + permissionStringBuilder.append("类:").append(getAnnotationNote(classPermissions.value(), classPermissions.mode())); + permissionStringBuilder.append("
"); + } + + SaCheckPermission methodPermission = handlerMethod.getMethodAnnotation(SaCheckPermission.class); + if (methodPermission != null) { + permissionStringBuilder.append(""); + permissionStringBuilder.append("方法:").append(getAnnotationNote(methodPermission.value(), methodPermission.mode())); + permissionStringBuilder.append("
"); + } + + if (permissionStringBuilder.length() > 0) { + permissionStringBuilder.insert(0, "权限校验:
"); + values.add(permissionStringBuilder.toString()); + } + + + StringBuilder roleStringBuilder = new StringBuilder(); + SaCheckRole classCheckRole = handlerMethod.getBeanType().getAnnotation(SaCheckRole.class); + if (classCheckRole != null) { + roleStringBuilder.append(""); + roleStringBuilder.append("类:").append(getAnnotationNote(classCheckRole.value(), classCheckRole.mode())); + roleStringBuilder.append("
"); + } + + SaCheckPermission methodCheckRole = handlerMethod.getMethodAnnotation(SaCheckPermission.class); + if (methodCheckRole != null) { + roleStringBuilder.append(""); + roleStringBuilder.append("方法:").append(getAnnotationNote(methodCheckRole.value(), methodCheckRole.mode())); + roleStringBuilder.append("
"); + } + + if (roleStringBuilder.length() > 0) { + roleStringBuilder.insert(0, "角色校验:
"); + values.add(roleStringBuilder.toString()); + } + + return values; + } + + private String getAnnotationNote(String[] values, SaMode mode) { + if (mode.equals(SaMode.AND)) { + return String.join(" 且 ", values); + } else { + return String.join(" 或 ", values); + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartBeanUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartBeanUtil.java new file mode 100644 index 0000000..d0c4bf1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartBeanUtil.java @@ -0,0 +1,94 @@ +package net.lab1024.sa.base.common.util; + +import org.springframework.beans.BeanUtils; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * bean相关工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2018-01-15 10:48:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SmartBeanUtil { + + /** + * 验证器 + */ + private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator(); + + /** + * 复制bean的属性 + * + * @param source 源 要复制的对象 + * @param target 目标 复制到此对象 + */ + public static void copyProperties(Object source, Object target) { + BeanUtils.copyProperties(source, target); + } + + /** + * 复制对象 + * + * @param source 源 要复制的对象 + * @param target 目标 复制到此对象 + * @param + * @return + */ + public static T copy(Object source, Class target) { + if (source == null || target == null) { + return null; + } + try { + T newInstance = target.newInstance(); + BeanUtils.copyProperties(source, newInstance); + return newInstance; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 复制list + * + * @param source + * @param target + * @param + * @param + * @return + */ + public static List copyList(List source, Class target) { + if (null == source || source.isEmpty()) { + return Collections.emptyList(); + } + return source.stream().map(e -> copy(e, target)).collect(Collectors.toList()); + } + + /** + * 手动验证对象 Model的属性 + * 需要配合 hibernate-validator 校验注解 + * + * @param t + * @return String 返回null代表验证通过,否则返回错误的信息 + */ + public static String verify(T t) { + // 获取验证结果 + Set> validate = VALIDATOR.validate(t); + if (validate.isEmpty()) { + // 验证通过 + return null; + } + // 返回错误信息 + List messageList = validate.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList()); + return messageList.toString(); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartBigDecimalUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartBigDecimalUtil.java new file mode 100644 index 0000000..fdd2a65 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartBigDecimalUtil.java @@ -0,0 +1,247 @@ +package net.lab1024.sa.base.common.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * BigDecimal 工具类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2018/01/17 13:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SmartBigDecimalUtil { + + /** + * 金额 保留小数点 2 + */ + public static final int AMOUNT_DECIMAL_POINT = 2; + + public static final BigDecimal ONE_HUNDRED = new BigDecimal("100"); + + /** + * 金额相关计算方法:四舍五入 保留2位小数点 + */ + public static class Amount { + + public static BigDecimal add(BigDecimal num1, BigDecimal num2) { + return setScale(num1.add(num2), AMOUNT_DECIMAL_POINT); + } + + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2) { + return setScale(num1.multiply(num2), AMOUNT_DECIMAL_POINT); + } + + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) { + return setScale(num1.subtract(num2), AMOUNT_DECIMAL_POINT); + } + + public static BigDecimal divide(BigDecimal num1, BigDecimal num2) { + return setScale(num1.divide(num2, RoundingMode.HALF_UP), AMOUNT_DECIMAL_POINT); + } + } + + + /** + * BigDecimal 加法 num1 + num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal add(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.add(num2), point); + } + + /** + * 累加 + * + * @param point + * @param array + * @return + */ + public static BigDecimal add(int point, BigDecimal... array) { + BigDecimal res = new BigDecimal(0); + for (BigDecimal item : array) { + if (item == null) { + res = res.add(BigDecimal.ZERO); + } else { + res = res.add(item); + } + } + return setScale(res, point); + } + + /** + * BigDecimal 乘法 num1 x num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.multiply(num2), point); + } + + /** + * BigDecimal 减法 num1 - num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.subtract(num2), point); + } + + /** + * BigDecimal 除法 num1/num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal divide(BigDecimal num1, BigDecimal num2, int point) { + return num1.divide(num2, point, RoundingMode.HALF_UP); + } + + /** + * 设置小数点类型为 四舍五入 + * + * @param num + * @param point + * @return BigDecimal + */ + public static BigDecimal setScale(BigDecimal num, int point) { + return num.setScale(point, RoundingMode.HALF_UP); + } + + /** + * 比较 num1 是否大于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isGreaterThan(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) > 0; + } + + /** + * 比较 num1 是否大于等于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isGreaterOrEqual(BigDecimal num1, BigDecimal num2) { + return isGreaterThan(num1, num2) || equals(num1, num2); + } + + /** + * 比较 num1 是否小于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isLessThan(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) < 0; + } + + /** + * 比较 num1 是否小于等于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isLessOrEqual(BigDecimal num1, BigDecimal num2) { + return isLessThan(num1, num2) || equals(num1, num2); + } + + /** + * 比较 num1 是否等于 num2 + * + * @param num1 + * @param num2 + * @return + */ + public static boolean equals(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) == 0; + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @param point 保留几位小数 + * @return String + */ + public static BigDecimal percent(Integer num1, Integer num2, int point) { + if (num1 == null || num2 == null) { + return BigDecimal.ZERO; + } + if (num2.equals(0)) { + return BigDecimal.ZERO; + } + return percent(new BigDecimal(num1), new BigDecimal(num2), point); + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @param point 保留几位小数 + * @return String + */ + public static BigDecimal percent(BigDecimal num1, BigDecimal num2, int point) { + if (num1 == null || num2 == null) { + return BigDecimal.ZERO; + } + if (equals(BigDecimal.ZERO, num2)) { + return BigDecimal.ZERO; + } + BigDecimal percent = num1.divide(num2, point + 2, RoundingMode.HALF_UP); + return percent.multiply(ONE_HUNDRED).setScale(point); + } + + /** + * 比较 num1,num2 返回最大的值 + * + * @param num1 + * @param num2 + * @return BigDecimal + */ + public static BigDecimal max(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) > 0 ? num1 : num2; + } + + /** + * 比较 num1,num2 返回最小的值 + * + * @param num1 + * @param num2 + * @return BigDecimal + */ + public static BigDecimal min(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) < 0 ? num1 : num2; + } + + public static void main(String[] args) { + System.out.println(percent(new BigDecimal("3"), new BigDecimal("11"), 2)); + System.out.println(percent(new BigDecimal("8"), new BigDecimal("11"), 2)); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartDateFormatterEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartDateFormatterEnum.java new file mode 100644 index 0000000..c19c07b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartDateFormatterEnum.java @@ -0,0 +1,79 @@ +package net.lab1024.sa.base.common.util; + + +import java.time.format.DateTimeFormatter; + +/** + * @Author 1024创新实验室: 胡克 + * @Date 2023/12/5 21:26:25 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * 1024创新实验室 ( https://1024lab.net ),2012-2023 + */ +public enum SmartDateFormatterEnum { + /** + * 日期格式 :年月日 yyyy-MM-dd + * 例:2021-10-15 + */ + YMD(DateTimeFormatter.ofPattern("yyyy-MM-dd")), + + /** + * 日期格式 :年月日 时分 yyyy-MM-dd HH:mm + * 例:2021-10-15 10:15 + */ + YMD_HM(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), + + /** + * 日期格式 :年月日 时分秒 yyyy-MM-dd HH:mm:ss + * 例:2021-10-15 10:15:00 + */ + YMD_HMS(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), + + /** + * 日期格式 :年月 yyyy-MM + * 例:2021-10 + */ + YM(DateTimeFormatter.ofPattern("yyyy-MM")), + + /** + * 日期格式:年月 MM-dd + * 例:10-15 + */ + MD(DateTimeFormatter.ofPattern("MM-dd")), + + /** + * 日期格式:年月 MM月dd日 + * 例:10月15日 + */ + CHINESE_MD(DateTimeFormatter.ofPattern("MM月dd日")), + + /** + * 日期格式 : yyyyMMddHHmmss + * 例:20091225091010 + */ + YMDHMS(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")), + + /** + * 日期格式 :时分秒 HH:mm:ss + * 例:10:15:00 + */ + HMS(DateTimeFormatter.ofPattern("HH:mm:ss")), + + /** + * 日期格式 :时分 HH:mm + * 例:10:15 + */ + HM(DateTimeFormatter.ofPattern("HH:mm")) + + ; + + private final DateTimeFormatter formatter; + + SmartDateFormatterEnum(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public DateTimeFormatter getFormatter() { + return formatter; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartEnumUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartEnumUtil.java new file mode 100644 index 0000000..290c4ad --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartEnumUtil.java @@ -0,0 +1,165 @@ +package net.lab1024.sa.base.common.util; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 枚举工具类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/10/10 18:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SmartEnumUtil { + + /** + * 校验参数与枚举类比较是否合法 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return boolean + * @Author 胡克 + */ + public static boolean checkEnum(Object value, Class enumClass) { + if (null == value) { + return false; + } + return Stream.of(enumClass.getEnumConstants()).anyMatch(e -> e.equalsValue(value)); + } + + /** + * 创建一个具有唯一array值的数组,每个值不包含在其他给定的数组中。 + * + * @param enumClass + * @param exclude + * @param + * @return + */ + public static List differenceValueList(Class enumClass, T... exclude) { + HashSet valueSet = new HashSet<>(); + if (exclude != null) { + valueSet.addAll(Stream.of(exclude).map(BaseEnum::getValue).collect(Collectors.toSet())); + } + + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> !valueSet.contains(e.getValue())) + .map(BaseEnum::getValue) + .collect(Collectors.toList()); + } + + /** + * 获取枚举类的说明 value : info 的形式 + * + * @param enumClass + * @return String + */ + public static String getEnumDesc(Class enumClass) { + BaseEnum[] enums = enumClass.getEnumConstants(); + // value : info 的形式 + StringBuilder sb = new StringBuilder(); + for (BaseEnum baseEnum : enums) { + sb.append(baseEnum.getValue()).append(":").append(baseEnum.getDesc()).append(","); + } + return sb.toString(); + } + + /** + * 获取与参数相匹配的枚举类实例的 说明 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return String 如无匹配枚举则返回null + */ + public static String getEnumDescByValue(Object value, Class enumClass) { + if (null == value) { + return null; + } + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> e.equalsValue(value)) + .findFirst() + .map(BaseEnum::getDesc) + .orElse(null); + } + + public static String getEnumDescByValueList(Collection values, Class enumClass) { + if (CollectionUtils.isEmpty(values)) { + return ""; + } + return Stream.of(enumClass.getEnumConstants()).filter(e -> values.contains(e.getValue())).map(BaseEnum::getDesc).collect(Collectors.joining(",")); + } + + /** + * 根据参数获取枚举类的实例 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return BaseEnum 无匹配值返回null + * @Author 胡克 + */ + public static T getEnumByValue(Object value, Class enumClass) { + if (null == value) { + return null; + } + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> e.equalsValue(value)) + .findFirst() + .orElse(null); + } + + /** + * 根据实例描述与获取枚举类的实例 + * + * @param desc 参数描述 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return BaseEnum 无匹配值返回null + * @Author 胡克 + */ + public static T getEnumByDesc(String desc, Class enumClass) { + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> Objects.equals(e.getDesc(), desc)) + .findFirst() + .orElse(null); + } + + + public static T getEnumByName(String name, Class enumClass) { + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> StringUtils.equalsIgnoreCase(e.toString(), name)) + .findFirst() + .orElse(null); + } + + + /** + * 根据lambda getter/setter 注入 + * + * @param list + * @param getter + * @param setter + * @param enumClass + * @param + */ + public static void inject(List list, Function getter, BiConsumer setter, Class enumClass) { + if (list == null || list.isEmpty()) { + return; + } + for (T t : list) { + Integer enumValue = getter.apply(t); + if (enumValue != null) { + setter.accept(t, getEnumDescByValue(enumValue, enumClass)); + } + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartExcelUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartExcelUtil.java new file mode 100644 index 0000000..175a230 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartExcelUtil.java @@ -0,0 +1,226 @@ +package net.lab1024.sa.base.common.util; + +import cn.idev.excel.FastExcel; +import cn.idev.excel.write.handler.SheetWriteHandler; +import cn.idev.excel.write.metadata.holder.WriteSheetHolder; +import cn.idev.excel.write.metadata.holder.WriteWorkbookHolder; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.opc.PackagePartName; +import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.openxml4j.opc.TargetMode; +import org.apache.poi.xssf.usermodel.XSSFPictureData; +import org.apache.poi.xssf.usermodel.XSSFRelation; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import javax.swing.*; +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; + +/** + * + * excel 工具类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2024/4/22 22:49:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2024 + */ +public final class SmartExcelUtil { + + /** + * 通用单sheet导出 + */ + public static void exportExcel(HttpServletResponse response, String fileName, String sheetName, Class head,Collection data) throws IOException { + // 设置下载消息头 + SmartResponseUtil.setDownloadFileHeader(response, fileName, null); + // 下载 + FastExcel.write(response.getOutputStream(), head) + .autoCloseStream(Boolean.FALSE) + .sheet(sheetName) + .doWrite(data); + } + + /** + * 通用单 sheet水印 导出 + */ + public static void exportExcelWithWatermark(HttpServletResponse response, String fileName, String sheetName, Class head,Collection data, String watermarkString) throws IOException { + // 设置下载消息头 + SmartResponseUtil.setDownloadFileHeader(response, fileName, null); + // 水印 + Watermark watermark = new Watermark(watermarkString); + // 一定要inMemory + FastExcel.write(response.getOutputStream(), head) + .inMemory(true) + .sheet(sheetName) + .registerWriteHandler(new CustomWaterMarkHandler(watermark)) + .doWrite(data); + } + + + @Slf4j + private static class CustomWaterMarkHandler implements SheetWriteHandler { + + private final Watermark watermark; + + public CustomWaterMarkHandler(Watermark watermark) { + this.watermark = watermark; + } + + @Override + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + BufferedImage bufferedImage = createWatermarkImage(); + XSSFWorkbook workbook = (XSSFWorkbook) writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook(); + try { + // 添加水印的具体操作 + addWatermarkToSheet(workbook, bufferedImage); + } catch (Exception e) { + log.error("添加水印出错:", e); + } + + } + + /** + * 创建水印图片 + * + * @return + */ + private BufferedImage createWatermarkImage() { + // 获取水印相关参数 + Font font = watermark.getFont(); + int width = watermark.getWidth(); + int height = watermark.getHeight(); + Color color = watermark.getColor(); + String text = watermark.getContent(); + + // 创建带有透明背景的 BufferedImage + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + + // 设置画笔字体、平滑、颜色 + g.setFont(font); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(color); + + // 计算水印位置和角度 + int y = watermark.getYAxis(); + int x = watermark.getXAxis(); + AffineTransform transform = AffineTransform.getRotateInstance(Math.toRadians(-watermark.getAngle()), 0, y); + g.setTransform(transform); + // 绘制水印文字 + g.drawString(text, x, y); + + // 释放资源 + g.dispose(); + + return image; + } + + private void addWatermarkToSheet(XSSFWorkbook workbook, BufferedImage watermarkImage) { + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { + ImageIO.write(watermarkImage, "png", os); + int pictureIdx = workbook.addPicture(os.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG); + XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx); + for (int i = 0; i < workbook.getNumberOfSheets(); i++) { + // 获取每个Sheet表 + XSSFSheet sheet = workbook.getSheetAt(i); + PackagePartName ppn = pictureData.getPackagePart().getPartName(); + String relType = XSSFRelation.IMAGES.getRelation(); + PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null); + sheet.getCTWorksheet().addNewPicture().setId(pr.getId()); + } + } catch (Exception e) { + // 处理ImageIO.write可能抛出的异常 + log.error("添加水印图片时发生错误", e); + } + } + } + + @Data + private static class Watermark { + + public Watermark(String content) { + this.content = content; + init(); + } + + public Watermark(String content, Color color, Font font, double angle) { + this.content = content; + this.color = color; + this.font = font; + this.angle = angle; + init(); + } + + /** + * 根据水印内容长度自适应水印图片大小,简单的三角函数 + */ + private void init() { + FontMetrics fontMetrics = new JLabel().getFontMetrics(this.font); + int stringWidth = fontMetrics.stringWidth(this.content); + int charWidth = fontMetrics.charWidth('A'); + this.width = (int) Math.abs(stringWidth * Math.cos(Math.toRadians(this.angle))) + 5 * charWidth; + this.height = (int) Math.abs(stringWidth * Math.sin(Math.toRadians(this.angle))) + 5 * charWidth; + this.yAxis = this.height; + this.xAxis = charWidth; + } + + /** + * 水印内容 + */ + private String content; + + /** + * 画笔颜色 + */ + private Color color = new Color(239,239,239); + + /** + * 字体样式 + */ + private Font font = new Font("Microsoft YaHei", Font.BOLD, 26); + + /** + * 水印宽度 + */ + private int width; + + /** + * 水印高度 + */ + private int height; + + /** + * 倾斜角度,非弧度制 + */ + private double angle = 25; + + /** + * 字体的y轴位置 + */ + private int yAxis = 50; + + /** + * 字体的X轴位置 + */ + private int xAxis; + + /** + * 水平倾斜度 + */ + private double shearX = 0.1; + + /** + * 垂直倾斜度 + */ + private double shearY = -0.26; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartIpUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartIpUtil.java new file mode 100644 index 0000000..254cdb7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartIpUtil.java @@ -0,0 +1,123 @@ +package net.lab1024.sa.base.common.util; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.constant.StringConst; +import org.lionsoul.ip2region.xdb.Searcher; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; + +/** + * IP工具类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/9/14 15:35:11 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ +@Slf4j +public class SmartIpUtil { + + private static Searcher IP_SEARCHER; + + /** + * 初始化数据 + * + * @param filePath + */ + public static void init(String filePath) { + + try { + byte[] cBuff = Searcher.loadContentFromFile(filePath); + IP_SEARCHER = Searcher.newWithBuffer(cBuff); + + } catch (Throwable e) { + log.error("初始化ip2region.xdb文件失败,报错信息:[{}]", e.getMessage(), e); + throw new RuntimeException("系统异常!"); + } + } + + + /** + * 自定义解析ip地址 + * + * @param ipStr ipStr + * @return 返回结果例 [河南省, 洛阳市, 洛龙区] + */ + public static List getRegionList(String ipStr) { + List regionList = new ArrayList<>(); + try { + if (SmartStringUtil.isEmpty(ipStr)) { + return regionList; + } + ipStr = ipStr.trim(); + String region = IP_SEARCHER.search(ipStr); + String[] split = region.split("\\|"); + regionList.addAll(Arrays.asList(split)); + } catch (Exception e) { + log.error("解析ip地址出错", e); + } + return regionList; + } + + /** + * 自定义解析ip地址 + * + * @param ipStr ipStr + * @return 返回结果例 河南省|洛阳市|洛龙区 + */ + public static String getRegion(String ipStr) { + try { + if (SmartStringUtil.isEmpty(ipStr)) { + return StringConst.EMPTY; + } + ipStr = ipStr.trim(); + return IP_SEARCHER.search(ipStr); + } catch (Exception e) { + log.error("解析ip地址出错", e); + return StringConst.EMPTY; + } + } + + /** + * 获取本机第一个ip + * + * @return + */ + public static String getLocalFirstIp() { + List list = getLocalIp(); + return list.size() > 0 ? list.get(0) : null; + } + + /** + * 获取本机ip + * + * @return + */ + public static List getLocalIp() { + List ipList = new ArrayList<>(); + try { + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + Enumeration inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + // 排除回环地址和IPv6地址 + if (!inetAddress.isLoopbackAddress() && !inetAddress.getHostAddress().contains(StringConst.COLON)) { + ipList.add(inetAddress.getHostAddress()); + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + return ipList; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartLocalDateUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartLocalDateUtil.java new file mode 100644 index 0000000..101c6ed --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartLocalDateUtil.java @@ -0,0 +1,124 @@ +package net.lab1024.sa.base.common.util; + +import java.time.*; +import java.time.format.TextStyle; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.Locale; + + +/** + * @Author 1024创新实验室:胡克 + * @Date 2023/12/5 22:25:43 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * 1024创新实验室 ( https://1024lab.net ),2012-2023 + */ +public class SmartLocalDateUtil { + + + /** + * 格式化 LocalDateTime 返回对应格式字符串 + * + * @param time + * @param formatterEnum {@link SmartDateFormatterEnum} + * @return + */ + public static String format(LocalDateTime time, SmartDateFormatterEnum formatterEnum) { + return time.format(formatterEnum.getFormatter()); + } + + /** + * 格式化 LocalDate返回对应格式字符串 + * + * @param date + * @param formatterEnum {@link SmartDateFormatterEnum} + * @return + */ + public static String format(LocalDate date, SmartDateFormatterEnum formatterEnum) { + return date.format(formatterEnum.getFormatter()); + } + + /** + * 解析时间字符串 返回LocalDateTime + * + * @param time + * @param formatterEnum {@link SmartDateFormatterEnum} + * @return + */ + public static LocalDateTime parse(String time, SmartDateFormatterEnum formatterEnum) { + return LocalDateTime.parse(time, formatterEnum.getFormatter()); + } + + /** + * 解析时间字符串 返回 LocalDate + * + * @param time + * @param formatterEnum {@link SmartDateFormatterEnum} + * @return + */ + public static LocalDate parseDate(String time, SmartDateFormatterEnum formatterEnum) { + return LocalDate.parse(time, formatterEnum.getFormatter()); + } + + /** + * 获取指定日期时间戳 + * + * @param time + * @return + */ + public static Long getTimestamp(LocalDateTime time) { + return time.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); + } + + /** + * 获取当前时间戳(秒) + * + * @return + */ + public static long nowSecond() { + return System.currentTimeMillis() / 1000; + } + + /** + * 将时间格式化为 星期几,例:星期一 ... 星期日 + * + * @param localDate + * @return + */ + public static String formatToChineseWeek(LocalDate localDate) { + return localDate.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE); + } + + /** + * 将时间格式化为 周几,例:周一 ... 周日 + * + * @param localDate + * @return + */ + public static String formatToChineseWeekZhou(LocalDate localDate) { + return formatToChineseWeek(localDate).replace("星期", "周"); + } + + public static LocalDateTime toLocalDateTime(Date date) { + return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime(); + } + + /** + * 获取当天剩余时间 单位 + * + * @param unit 时间单位 + * @return + */ + public static Long getDayBalanceTime(ChronoUnit unit) { + LocalDateTime now = LocalDateTime.now(); + return Duration.between(now, now.plusDays(1L).with(LocalTime.MIN)).get(unit); + } + + public static void main(String[] args) { + System.out.println(SmartLocalDateUtil.format(LocalDateTime.now(), SmartDateFormatterEnum.YMD_HMS)); + System.out.println(SmartLocalDateUtil.format(LocalDateTime.now(), SmartDateFormatterEnum.YMD_HM)); + System.out.println(SmartLocalDateUtil.parse("2021-10-15 10:10:00", SmartDateFormatterEnum.YMD_HMS)); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartPageUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartPageUtil.java new file mode 100644 index 0000000..eb88c58 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartPageUtil.java @@ -0,0 +1,118 @@ +package net.lab1024.sa.base.common.util; + +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.exception.BusinessException; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 分页工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-04-23 20:51:40 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class SmartPageUtil { + + /** + * 转换为查询参数 + */ + public static Page convert2PageQuery(PageParam pageParam) { + Page page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize()); + + if (pageParam.getSearchCount() != null) { + page.setSearchCount(pageParam.getSearchCount()); + } + + List sortItemList = pageParam.getSortItemList(); + if (CollectionUtils.isEmpty(sortItemList)) { + return page; + } + + // 设置排序字段并检测是否含有sql注入 + List orderItemList = new ArrayList<>(); + for (PageParam.SortItem sortItem : sortItemList) { + + if (SmartStringUtil.isEmpty(sortItem.getColumn())) { + continue; + } + + if (SqlInjectionUtils.check(sortItem.getColumn())) { + log.error("《存在SQL注入:》 : {}", sortItem.getColumn()); + throw new BusinessException("存在SQL注入风险,请联系技术工作人员!"); + } + orderItemList.add(sortItem.getIsAsc() ? OrderItem.asc(sortItem.getColumn()) : OrderItem.desc(sortItem.getColumn())); + } + page.setOrders(orderItemList); + return page; + } + + /** + * 转换为 PageResult 对象 + */ + public static PageResult convert2PageResult(Page page, List sourceList, Class targetClazz) { + return convert2PageResult(page, SmartBeanUtil.copyList(sourceList, targetClazz)); + } + + /** + * 转换为 PageResult 对象 + */ + public static PageResult convert2PageResult(Page page, List sourceList) { + PageResult pageResult = new PageResult<>(); + pageResult.setPageNum(page.getCurrent()); + pageResult.setPageSize(page.getSize()); + pageResult.setTotal(page.getTotal()); + pageResult.setPages(page.getPages()); + pageResult.setList(sourceList); + pageResult.setEmptyFlag(CollectionUtils.isEmpty(sourceList)); + return pageResult; + } + + /** + * 转换分页结果对象 + */ + public static PageResult convert2PageResult(PageResult pageResult, Class targetClazz) { + PageResult newPageResult = new PageResult<>(); + newPageResult.setPageNum(pageResult.getPageNum()); + newPageResult.setPageSize(pageResult.getPageSize()); + newPageResult.setTotal(pageResult.getTotal()); + newPageResult.setPages(pageResult.getPages()); + newPageResult.setEmptyFlag(pageResult.getEmptyFlag()); + newPageResult.setList(SmartBeanUtil.copyList(pageResult.getList(), targetClazz)); + return newPageResult; + } + + public static PageResult subListPage(Integer pageNum, Integer pageSize, List list) { + PageResult pageRet = new PageResult(); + //总条数 + int count = list.size(); + int pages = count % pageSize == 0 ? count / pageSize : (count / pageSize + 1); + int fromIndex = (pageNum - 1) * pageSize; + int toIndex = Math.min(pageNum * pageSize, count); + + if (pageNum > pages) { + pageRet.setList(Lists.newLinkedList()); + pageRet.setPageNum(pageNum.longValue()); + pageRet.setPages((long) pages); + pageRet.setTotal((long) count); + return pageRet; + } + List pageList = list.subList(fromIndex, toIndex); + pageRet.setList(pageList); + pageRet.setPageNum(pageNum.longValue()); + pageRet.setPages((long) pages); + pageRet.setTotal((long) count); + return pageRet; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartRequestUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartRequestUtil.java new file mode 100644 index 0000000..aab0230 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartRequestUtil.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.base.common.util; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.RequestUser; + +/** + * 请求用户 工具类 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class SmartRequestUtil { + + private static final ThreadLocal REQUEST_THREAD_LOCAL = new ThreadLocal<>(); + + public static void setRequestUser(RequestUser requestUser) { + if(requestUser == null){ + return; + } + REQUEST_THREAD_LOCAL.set(requestUser); + } + + public static RequestUser getRequestUser() { + return REQUEST_THREAD_LOCAL.get(); + } + + public static Long getRequestUserId() { + RequestUser requestUser = getRequestUser(); + return null == requestUser ? null : requestUser.getUserId(); + } + + + public static void remove() { + REQUEST_THREAD_LOCAL.remove(); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartResponseUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartResponseUtil.java new file mode 100644 index 0000000..95995bd --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartResponseUtil.java @@ -0,0 +1,66 @@ +package net.lab1024.sa.base.common.util; + +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.MediaTypeFactory; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import static cn.hutool.core.util.CharsetUtil.UTF_8; + +/** + * 返回工具栏 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/11/25 18:51:32 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Slf4j +public class SmartResponseUtil { + + public static void write(HttpServletResponse response, ResponseDTO responseDTO) { + // 重置response + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setCharacterEncoding(UTF_8); + + try { + response.getWriter().write(JSON.toJSONString(responseDTO)); + response.flushBuffer(); + } catch (IOException ex) { + log.error(ex.getMessage(), ex); + throw new RuntimeException(ex); + } + } + + public static void setDownloadFileHeader(HttpServletResponse response, String fileName) { + setDownloadFileHeader(response, fileName, null); + } + + public static void setDownloadFileHeader(HttpServletResponse response, String fileName, Long fileSize) { + response.setCharacterEncoding(UTF_8); + if (fileSize != null) { + response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileSize)); + } + + if (SmartStringUtil.isNotEmpty(fileName)) { + response.setHeader(HttpHeaders.CONTENT_TYPE, MediaTypeFactory.getMediaType(fileName).orElse(MediaType.APPLICATION_OCTET_STREAM) + ";charset=utf-8"); + try { + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION); + } + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartStringUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartStringUtil.java new file mode 100644 index 0000000..da8ff28 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartStringUtil.java @@ -0,0 +1,327 @@ +package net.lab1024.sa.base.common.util; + + +import cn.hutool.core.util.StrUtil; + +import java.util.*; + +/** + * 独有的字符串工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SmartStringUtil extends StrUtil { + + // ===============split ======================= + + public static Set splitConvertToSet(String str, String split) { + if (isEmpty(str)) { + return new HashSet(); + } + String[] splitArr = str.split(split); + HashSet set = new HashSet(splitArr.length); + Collections.addAll(set, splitArr); + return set; + } + + public static List splitConvertToList(String str, String split) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] splitArr = str.split(split); + ArrayList list = new ArrayList(splitArr.length); + list.addAll(Arrays.asList(splitArr)); + return list; + } + + // ===============split Integer======================= + + public static List splitConvertToIntList(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + int parseInt = Integer.parseInt(strArr[i]); + list.add(parseInt); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static Set splitConvertToIntSet(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new HashSet(); + } + String[] strArr = str.split(split); + HashSet set = new HashSet(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + int parseInt = Integer.parseInt(strArr[i]); + set.add(parseInt); + } catch (NumberFormatException e) { + set.add(defaultVal); + continue; + } + } + return set; + } + + public static Set splitConvertToIntSet(String str, String split) { + return splitConvertToIntSet(str, split, 0); + } + + public static List splitConvertToIntList(String str, String split) { + return splitConvertToIntList(str, split, 0); + } + + public static int[] splitConvertToIntArray(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new int[0]; + } + String[] strArr = str.split(split); + int[] result = new int[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Integer.parseInt(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static int[] splitConvertToIntArray(String str, String split) { + return splitConvertToIntArray(str, split, 0); + } + + // ===============split 2 Long======================= + + public static List splitConvertToLongList(String str, String split, long defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + long parseLong = Long.parseLong(strArr[i]); + list.add(parseLong); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToLongList(String str, String split) { + return splitConvertToLongList(str, split, 0L); + } + + public static long[] splitConvertToLongArray(String str, String split, long defaultVal) { + if (isEmpty(str)) { + return new long[0]; + } + String[] strArr = str.split(split); + long[] result = new long[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Long.parseLong(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static long[] splitConvertToLongArray(String str, String split) { + return splitConvertToLongArray(str, split, 0L); + } + + // ===============split convert byte======================= + + public static List splitConvertToByteList(String str, String split, byte defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + byte parseByte = Byte.parseByte(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToByteList(String str, String split) { + return splitConvertToByteList(str, split, (byte) 0); + } + + public static byte[] splitConvertToByteArray(String str, String split, byte defaultVal) { + if (isEmpty(str)) { + return new byte[0]; + } + String[] strArr = str.split(split); + byte[] result = new byte[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Byte.parseByte(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static byte[] splitConvertToByteArray(String str, String split) { + return splitConvertToByteArray(str, split, (byte) 0); + } + + // ===============split convert double======================= + + public static List splitConvertToDoubleList(String str, String split, double defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + double parseByte = Double.parseDouble(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToDoubleList(String str, String split) { + return splitConvertToDoubleList(str, split, 0); + } + + public static double[] splitConvertToDoubleArray(String str, String split, double defaultVal) { + if (isEmpty(str)) { + return new double[0]; + } + String[] strArr = str.split(split); + double[] result = new double[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Double.parseDouble(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static double[] splitConvertToDoubleArray(String str, String split) { + return splitConvertToDoubleArray(str, split, 0); + } + + // ===============split convert float======================= + + public static List splitConvertToFloatList(String str, String split, float defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + float parseByte = Float.parseFloat(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToFloatList(String str, String split) { + return splitConvertToFloatList(str, split, 0f); + } + + public static float[] splitConvertToFloatArray(String str, String split, float defaultVal) { + if (isEmpty(str)) { + return new float[0]; + } + String[] strArr = str.split(split); + float[] result = new float[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Float.parseFloat(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static float[] splitConvertToFloatArray(String str, String split) { + return splitConvertToFloatArray(str, split, 0f); + } + + + public static String upperCaseFirstChar(String str) { + if (str != null && !str.isEmpty()) { + char firstChar = str.charAt(0); + if (Character.isUpperCase(firstChar)) { + return str; + } else { + char[] values = str.toCharArray(); + values[0] = Character.toUpperCase(firstChar); + return new String(values); + } + } else { + return str; + } + } + + public static String replace(String content, int begin, int end, String newStr) { + if (begin < content.length() && begin >= 0) { + if (end <= content.length() && end >= 0) { + if (begin > end) { + return content; + } else { + StringBuilder starStr = new StringBuilder(); + + for (int i = begin; i < end; ++i) { + starStr.append(newStr); + } + + return content.substring(0, begin) + starStr + content.substring(end); + } + } else { + return content; + } + } else { + return content; + } + } + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartVerificationUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartVerificationUtil.java new file mode 100644 index 0000000..aec6a8e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/util/SmartVerificationUtil.java @@ -0,0 +1,98 @@ +package net.lab1024.sa.base.common.util; + +import java.util.regex.Pattern; + +/** + * 验证工具类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/11/06 10:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SmartVerificationUtil { + + /** + * 手机号码验证规则 + */ + public static final String PHONE_REGEXP = "^1[0-9]{10}"; + + /** + * 固定号码验证规则 + */ + public static final String FIXED_PHONE_REGEXP = "^0\\d{2,3}-[1-9]\\d{6,7}$"; + + /** + * 密码正则校验 + */ + public static final String PWD_REGEXP = "^[A-Za-z0-9.]{6,15}$"; + + /** + * 车牌号 + */ + public static final String CAR_NUMBER = + "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|" + "([A-HJ-Z" + "]{1}[A-D0-9]{1}[0-9]{3}警)))|" + + "([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|" + "([VKHBSLJNGCE]{1}[A-DJ-PR" + "-TVY]{1}[0-9]{5})"; + + /** + * 日期年月日校验 yyyy-MM-dd HH:mm:ss + */ + public static final String DATE_TIME = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9" + + "]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; + + /** + * 日期校验 yyyy-MM-dd + */ + public static final String DATE = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))" + + "|(02-(0[1-9]|[1][0-9]|2[0-8])))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)" + "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9" + + "][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|(" + "(([0-9]{2})(0[48]|[2468][048]|[13579][26])|(" + "(0[48" + "]|[2468][048]|[3579][26])00))-02-29)"; + + public static final String DATE_TIME_HM = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9])$"; + + /** + * 年月校验 例: 2019-10 + */ + public static final String YEAR_MONTH = "^\\d{4}-((0([1-9]))|(1(0|1|2)))$"; + + /** + * 时间区间验证 10:23-19:00 + */ + public static final String TIME_SECTION = "^(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])-(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])$"; + + /** + * 时间验证 10:23 + */ + public static final String TIME = "^(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])$"; + + /** + * 身份证号 + */ + public static final String ID_CARD = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"; + + /** + * URL + */ + public static final String URL = "[a-zA-z]+://[^\\s]*"; + + /** + * 邮箱 + */ + public static final String EMAIL = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?"; + + /** + * 整数 + */ + public static final String INTEGER = "^-?[1-9]\\d*$"; + + /** + * 小数 + */ + public static final String DOUBLE = "^-?[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$"; + + + public static void main(String[] args) { + boolean matches = Pattern.matches(INTEGER, "1"); + System.out.println(matches); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/validator/enumeration/CheckEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/common/validator/enumeration/CheckEnum.java new file mode 100644 index 0000000..5bbe857 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/validator/enumeration/CheckEnum.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.base.common.validator.enumeration; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义的属性校验注解,为了方便与校验属性的值是否为合法的枚举值 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/11/11 15:31 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = EnumValidator.class)// 自定义验证的处理类 +public @interface CheckEnum { + + /** + * 默认的错误提示信息 + * + * @return String + */ + String message(); + + /** + * 枚举类对象 必须实现BaseEnum接口 + * + */ + Class value(); + + /** + * 是否必须 + * + * @return boolean + */ + boolean required() default false; + + //下面这两个属性必须添加 :不然会报错 + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/common/validator/enumeration/EnumValidator.java b/yun-base/src/main/java/net/lab1024/sa/base/common/validator/enumeration/EnumValidator.java new file mode 100644 index 0000000..72891be --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/common/validator/enumeration/EnumValidator.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.base.common.validator.enumeration; + + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 枚举类校验器 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/11/11 15:34 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class EnumValidator implements ConstraintValidator { + + /** + * 枚举类实例集合 + */ + private List enumValList; + + /** + * 是否必须 + */ + private boolean required; + + @Override + public void initialize(CheckEnum constraintAnnotation) { + // 获取注解传入的枚举类对象 + required = constraintAnnotation.required(); + Class enumClass = constraintAnnotation.value(); + enumValList = Stream.of(enumClass.getEnumConstants()).map(BaseEnum::getValue).collect(Collectors.toList()); + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) { + // 判断是否必须 + if (null == value) { + return !required; + } + + if (value instanceof List) { + // 如果为 List 集合数据 + return this.checkList((List) value); + } + + // 校验是否为合法的枚举值 + return enumValList.contains(value); + } + + /** + * 校验集合类型 + * + */ + private boolean checkList(List list) { + if (required && list.isEmpty()) { + // 必须的情况下 list 不能为空 + return false; + } + // 校验是否重复 + long count = list.stream().distinct().count(); + if (count != list.size()) { + return false; + } + return enumValList.containsAll(list); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/AsyncConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/AsyncConfig.java new file mode 100644 index 0000000..4a14ab4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/AsyncConfig.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.base.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * 异步调用线程配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Configuration +public class AsyncConfig { + + /** + * 线程池 配置bean名称 + */ + public static final String ASYNC_EXECUTOR_THREAD_NAME = "smart-async-executor"; + + /** + * 配置线程池 + * + * @return + */ + @Bean(name = ASYNC_EXECUTOR_THREAD_NAME) + public AsyncTaskExecutor executor() { + int processors = Runtime.getRuntime().availableProcessors(); + int threadCount = Math.max(1, processors - 1); + ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); + // 核心线程数量 + taskExecutor.setCorePoolSize(threadCount); + // 最大线程数量 + taskExecutor.setMaxPoolSize(threadCount); + taskExecutor.setThreadNamePrefix(ASYNC_EXECUTOR_THREAD_NAME); + taskExecutor.initialize(); + return taskExecutor; + } + + /** + * spring 异步任务 异常配置 + */ + @Configuration + public static class AsyncExceptionConfig implements AsyncConfigurer { + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return new AsyncExceptionHandler(); + } + } + + /** + * 自定义异常处理 + */ + public static class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { + @Override + public void handleUncaughtException(Throwable throwable, Method method, Object... objects) { + log.error("异步任务发生异常:{}, 参数:{}, ", method.getDeclaringClass().getSimpleName() + "." + method.getName(), Arrays.toString(objects), throwable); + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/CacheConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/CacheConfig.java new file mode 100644 index 0000000..665a23f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/CacheConfig.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.base.config; + +import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer; +import net.lab1024.sa.base.module.support.cache.CacheService; +import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl; +import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl; +import net.lab1024.sa.base.module.support.redis.CustomRedisCacheManager; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cache.CacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializationContext; + +import javax.annotation.Resource; + +/** + * 缓存配置 + * + */ +@Configuration +public class CacheConfig { + + private static final String REDIS_CACHE = "redis"; + private static final String CAFFEINE_CACHE = "caffeine"; + + + @Resource + private RedisConnectionFactory redisConnectionFactory; + + /** + * 创建自定义Redis缓存管理器Bean 整合spring-cache + * Redis连接工厂,用于建立与Redis服务器的连接 + * + * @return CacheManager Redis缓存管理器实例 + */ + @Bean + @ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE) + public CacheManager cacheManager() { + // 使用非阻塞模式的缓存写入器,适用于大多数高并发场景 + RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); + + // 构建默认缓存配置 + RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig() + // 禁止缓存 null 值,避免缓存穿透 + .disableCachingNullValues() + .computePrefixWith(name -> "cache:" + name + ":") + // 使用 FastJSON 序列化缓存值,支持复杂对象 + .serializeValuesWith(RedisSerializationContext.SerializationPair + .fromSerializer(new GenericFastJsonRedisSerializer())); + + // 返回自定义缓存管理器,支持 cacheName#ttl 格式与永久缓存(#-1) + return new CustomRedisCacheManager(redisCacheWriter, defaultCacheConfig); + } + + +@Bean +@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE) +public CacheService redisCacheService() { + return new RedisCacheServiceImpl(); +} + +@Bean +@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = CAFFEINE_CACHE) +public CacheService caffeineCacheService() { + return new CaffeineCacheServiceImpl(); +} + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/CorsFilterConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/CorsFilterConfig.java new file mode 100644 index 0000000..7ccccff --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/CorsFilterConfig.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +/** + * 跨域配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/11/15 20:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +@Conditional(SystemEnvironmentConfig.class) +public class CorsFilterConfig { + + @Value("${access-control-allow-origin}") + private String accessControlAllowOrigin; + + /** + * 跨域配置 + */ + @Bean + public CorsFilter corsFilter () { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // 设置访问源地址 + config.addAllowedOriginPattern(accessControlAllowOrigin); + // 设置访问源请求头 + config.addAllowedHeader("*"); + // 设置访问源请求方法 + config.addAllowedMethod("*"); + // 对接口配置跨域设置 + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/DataSourceConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/DataSourceConfig.java new file mode 100644 index 0000000..196510f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/DataSourceConfig.java @@ -0,0 +1,201 @@ +package net.lab1024.sa.base.config; + +import com.alibaba.druid.filter.Filter; +import com.alibaba.druid.filter.stat.StatFilter; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.support.http.StatViewServlet; +import com.alibaba.druid.support.http.WebStatFilter; +import com.alibaba.druid.support.spring.stat.DruidStatInterceptor; +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.core.config.GlobalConfig; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.DataScopePlugin; +import net.lab1024.sa.base.handler.MybatisPlusFillHandler; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.JdkRegexpMethodPointcut; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 数据源配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2017-11-28 15:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Configuration +public class DataSourceConfig { + + @Value("${spring.datasource.driver-class-name}") + String driver; + + @Value("${spring.datasource.url}") + String url; + + @Value("${spring.datasource.username}") + String username; + + @Value("${spring.datasource.password}") + String password; + + @Value("${spring.datasource.initial-size}") + int initialSize; + + @Value("${spring.datasource.min-idle}") + int minIdle; + + @Value("${spring.datasource.max-active}") + int maxActive; + + @Value("${spring.datasource.max-wait}") + long maxWait; + + @Value("${spring.datasource.time-between-eviction-runs-millis}") + long timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.min-evictable-idle-time-millis}") + long minEvictableIdleTimeMillis; + + @Value("${spring.datasource.filters}") + String filters; + + @Value("${spring.datasource.druid.username}") + String druidUserName; + + @Value("${spring.datasource.druid.password}") + String druidPassword; + + @Value("${spring.datasource.druid.login.enabled}") + boolean druidLoginEnable; + + @Value("${spring.datasource.druid.method.pointcut}") + String methodPointcut; + + @javax.annotation.Resource + private MybatisPlusInterceptor paginationInterceptor; + + @javax.annotation.Resource + private DataScopePlugin dataScopePlugin; + + @Bean + @Primary + public DataSource druidDataSource() { + DruidDataSource druidDataSource = new DruidDataSource(); + druidDataSource.setDbType(DbType.MYSQL.getDb()); + druidDataSource.setDriverClassName(driver); + druidDataSource.setUrl(url); + druidDataSource.setUsername(username); + druidDataSource.setPassword(password); + druidDataSource.setInitialSize(initialSize); + druidDataSource.setMinIdle(minIdle); + druidDataSource.setMaxActive(maxActive); + druidDataSource.setMaxWait(maxWait); + druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + druidDataSource.setValidationQuery("SELECT 1"); + try { + druidDataSource.setFilters(filters); + ArrayList arrayList = new ArrayList<>(); + StatFilter statFilter = new StatFilter(); + statFilter.setMergeSql(true); + statFilter.setSlowSqlMillis(1000); + statFilter.setLogSlowSql(true); + arrayList.add(statFilter); + druidDataSource.setProxyFilters(arrayList); + druidDataSource.init(); + } catch (SQLException e) { + log.error("初始化数据源出错", e); + } + + return druidDataSource; + } + + @Bean + public SqlSessionFactory sqlSessionFactory() throws Exception { + MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean(); + factoryBean.setDataSource(druidDataSource()); + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = resolver.getResources("classpath*:/mapper/**/*.xml"); + factoryBean.setMapperLocations(resources); + + // 设置 MyBatis-Plus 分页插件 注意此处myBatisPlugin一定要放在后面 + List pluginsList = new ArrayList<>(); + pluginsList.add(paginationInterceptor); + if (dataScopePlugin != null) { + pluginsList.add(dataScopePlugin); + } + factoryBean.setPlugins(pluginsList.toArray(new Interceptor[0])); + // 添加字段自动填充处理 + factoryBean.setGlobalConfig(new GlobalConfig().setBanner(false).setMetaObjectHandler(new MybatisPlusFillHandler())); + + return factoryBean.getObject(); + } + + /** + * 非正式环境 才加载 + * + * @return + */ + @Conditional(SystemEnvironmentConfig.class) + @Bean + public ServletRegistrationBean druidServlet() { + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean<>(); + servletRegistrationBean.setServlet(new StatViewServlet()); + servletRegistrationBean.addUrlMappings("/druid/*"); + Map initParameters = new HashMap(); + //不设置用户名密码可以直接通过druid/index.html访问 + if (druidLoginEnable) { + initParameters.put("loginUsername", druidUserName); + initParameters.put("loginPassword", druidPassword); + } + initParameters.put("resetEnable", "false"); + servletRegistrationBean.setInitParameters(initParameters); + return servletRegistrationBean; + } + + @Bean + public FilterRegistrationBean filterRegistrationBean() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(new WebStatFilter()); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/*"); + return filterRegistrationBean; + } + + @Bean + public JdkRegexpMethodPointcut jdkRegexpMethodPointcut() { + JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut(); + jdkRegexpMethodPointcut.setPatterns(methodPointcut); + return jdkRegexpMethodPointcut; + } + + @Bean + public DefaultPointcutAdvisor defaultPointcutAdvisor() { + DefaultPointcutAdvisor pointcutAdvisor = new DefaultPointcutAdvisor(); + pointcutAdvisor.setPointcut(jdkRegexpMethodPointcut()); + pointcutAdvisor.setAdvice(new DruidStatInterceptor()); + return pointcutAdvisor; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/FileConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/FileConfig.java new file mode 100644 index 0000000..97dce11 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/FileConfig.java @@ -0,0 +1,110 @@ +package net.lab1024.sa.base.config; + +import lombok.Data; +import net.lab1024.sa.base.module.support.file.service.FileStorageCloudServiceImpl; +import net.lab1024.sa.base.module.support.file.service.FileStorageLocalServiceImpl; +import net.lab1024.sa.base.module.support.file.service.IFileStorageService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.S3Configuration; + +import java.net.URI; + +/** + * 文件上传 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019-09-02 23:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@Configuration +public class FileConfig implements WebMvcConfigurer { + + private static final String HTTPS = "https://"; + + private static final String HTTP = "http://"; + + private static final String MODE_CLOUD = "cloud"; + + private static final String MODE_LOCAL = "local"; + + @Value("${file.storage.cloud.region}") + private String region; + + @Value("${file.storage.cloud.endpoint}") + private String endpoint; + + @Value("${file.storage.cloud.bucket-name}") + private String bucketName; + + @Value("${file.storage.cloud.access-key}") + private String accessKey; + + @Value("${file.storage.cloud.secret-key}") + private String secretKey; + + @Value("${file.storage.cloud.private-url-expire-seconds}") + private Long privateUrlExpireSeconds; + + @Value("${file.storage.cloud.url-prefix}") + private String urlPrefix; + + @Value("${file.storage.local.upload-path}") + private String uploadPath; + + @Value("${file.storage.mode}") + private String mode; + + /** + * 初始化 云oss client 配置 + * + * @return + */ + @Bean + @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = MODE_CLOUD) + public S3Client initAmazonS3() { + return S3Client.builder() + .region(Region.AWS_GLOBAL) + .endpointOverride(URI.create((urlPrefix.startsWith(HTTPS) ? HTTPS : HTTP) + endpoint)) + .credentialsProvider( + StaticCredentialsProvider.create( + AwsBasicCredentials.create(accessKey, secretKey))) + .serviceConfiguration(S3Configuration.builder() + .pathStyleAccessEnabled(true) + .chunkedEncodingEnabled(false) + .build()) + .build(); + } + + @Bean + @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = MODE_CLOUD) + public IFileStorageService initCloudFileService() { + return new FileStorageCloudServiceImpl(); + } + + @Bean + @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = MODE_LOCAL) + public IFileStorageService initLocalFileService() { + return new FileStorageLocalServiceImpl(); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + if (MODE_LOCAL.equals(mode)) { + String path = uploadPath.endsWith("/") ? uploadPath : uploadPath + "/"; + registry.addResourceHandler(FileStorageLocalServiceImpl.UPLOAD_MAPPING + "/**").addResourceLocations("file:" + path); + } + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/HeartBeatConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/HeartBeatConfig.java new file mode 100644 index 0000000..5f04e5a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/HeartBeatConfig.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.config; + +import net.lab1024.sa.base.module.support.heartbeat.core.HeartBeatManager; +import net.lab1024.sa.base.module.support.heartbeat.core.IHeartBeatRecordHandler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.Resource; + +/** + * 心跳配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2018/10/9 18:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +public class HeartBeatConfig { + + /** + * 间隔时间 + */ + @Value("${heart-beat.interval-seconds}") + private Long intervalSeconds; + + @Resource + private IHeartBeatRecordHandler heartBeatRecordHandler; + + @Bean + public HeartBeatManager heartBeatManager() { + return new HeartBeatManager(intervalSeconds * 1000L, heartBeatRecordHandler); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/JsonConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/JsonConfig.java new file mode 100644 index 0000000..257899e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/JsonConfig.java @@ -0,0 +1,96 @@ +package net.lab1024.sa.base.config; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import net.lab1024.sa.base.common.json.serializer.LongJsonSerializer; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeParseException; + +/** + * json 序列化配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2017-11-28 15:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +public class JsonConfig { + + @Bean + public Jackson2ObjectMapperBuilderCustomizer customizer() { + return builder -> { + builder.deserializers(new LocalDateDeserializer(DatePattern.NORM_DATE_FORMAT.getDateTimeFormatter())); + builder.deserializers(new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter())); + builder.serializers(new LocalDateSerializer(DatePattern.NORM_DATE_FORMAT.getDateTimeFormatter())); + builder.serializers(new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter())); + builder.serializerByType(Long.class, LongJsonSerializer.INSTANCE); + builder.serializerByType(Long.TYPE, LongJsonSerializer.INSTANCE); + builder.serializerByType(BigInteger.class, ToStringSerializer.instance); + builder.serializerByType(BigDecimal.class, ToStringSerializer.instance); + }; + } + + + /** + * string 转为 LocalDateTime 配置类 + * + * @author 卓大 + */ + @Configuration + public static class StringToLocalDateTime implements Converter { + + @Override + public LocalDateTime convert(String str) { + if (StringUtils.isBlank(str)) { + return null; + } + LocalDateTime localDateTime; + try { + localDateTime = LocalDateTimeUtil.parse(str, DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter()); + } catch (DateTimeParseException e) { + throw new RuntimeException("请输入正确的日期格式:yyyy-MM-dd HH:mm:ss"); + } + return localDateTime; + } + } + + + /** + * string 转为 LocalDate 配置类 + * + * @author 卓大 + */ + @Configuration + public static class StringToLocalDate implements Converter { + + @Override + public LocalDate convert(String str) { + if (StringUtils.isBlank(str)) { + return null; + } + LocalDate localDate; + try { + localDate = LocalDateTimeUtil.parseDate(str, DatePattern.NORM_DATE_FORMAT.getDateTimeFormatter()); + } catch (DateTimeParseException e) { + throw new RuntimeException("请输入正确的日期格式:yyyy-MM-dd"); + } + return localDate; + } + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/MybatisPlusConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/MybatisPlusConfig.java new file mode 100644 index 0000000..24117bc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/MybatisPlusConfig.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.base.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +/** + * mp 插件 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@EnableTransactionManagement +@Configuration +public class MybatisPlusConfig { + + /** + * 分页插件 + */ + @Bean + public MybatisPlusInterceptor paginationInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/RedisConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/RedisConfig.java new file mode 100644 index 0000000..24a1477 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/RedisConfig.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.base.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import javax.annotation.Resource; + +/** + * redis配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +public class RedisConfig { + + @Resource + private RedisConnectionFactory factory; + + @Bean + public RedisTemplate redisTemplate() { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.registerModule(new JavaTimeModule()) + .configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + // enableDefaultTyping 官方已弃用 所以改为 activateDefaultTyping + om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(jackson2JsonRedisSerializer); + template.setHashKeySerializer(jackson2JsonRedisSerializer); + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.setDefaultSerializer(new StringRedisSerializer()); + template.afterPropertiesSet(); + return template; + } + + @Bean + public HashOperations hashOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForHash(); + } + + @Bean + public ValueOperations valueOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForValue(); + } + + @Bean + public ListOperations listOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForList(); + } + + @Bean + public SetOperations setOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForSet(); + } + + @Bean + public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForZSet(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/RepeatSubmitConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/RepeatSubmitConfig.java new file mode 100644 index 0000000..c077e41 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/RepeatSubmitConfig.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.config; + +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.repeatsubmit.RepeatSubmitAspect; +import net.lab1024.sa.base.module.support.repeatsubmit.ticket.RepeatSubmitRedisTicket; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +/** + * 重复提交配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/9 18:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +public class RepeatSubmitConfig { + + @Resource + private RedisTemplate redisTemplate; + + @Bean + public RepeatSubmitAspect repeatSubmitAspect() { + RepeatSubmitRedisTicket ticket = new RepeatSubmitRedisTicket(redisTemplate, this::ticket); + return new RepeatSubmitAspect(ticket); + } + + /** + * 获取指明某个用户的凭证 + */ + private String ticket(HttpServletRequest request) { + Long userId = SmartRequestUtil.getRequestUserId(); + if (null == userId) { + return StringConst.EMPTY; + } + return request.getServletPath() + "_" + userId; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/RestTemplateConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/RestTemplateConfig.java new file mode 100644 index 0000000..1a3cdf4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/RestTemplateConfig.java @@ -0,0 +1,130 @@ +package net.lab1024.sa.base.config; + +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * http请求配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +public class RestTemplateConfig { + + @Value("${http.pool.max-total}") + private Integer maxTotal; + + @Value("${http.pool.connect-timeout}") + private Integer connectTimeout; + + @Value("${http.pool.read-timeout}") + private Integer readTimeout; + + @Value("${http.pool.write-timeout}") + private Integer writeTimeout; + + @Value("${http.pool.keep-alive}") + private Integer keepAlive; + + @Bean + public RestTemplate restTemplate() { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setRequestFactory(this.clientHttpRequestFactory()); + List> messageConverterList = restTemplate.getMessageConverters(); + messageConverterList.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8)); + messageConverterList.addAll(this.converters()); + return restTemplate; + } + + public List> converters() { + List> converters = new ArrayList<>(); + HttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8); + FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); + List fastMediaTypes = new ArrayList<>(); + fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); + fastMediaTypes.add(MediaType.APPLICATION_JSON); + fastConverter.setSupportedMediaTypes(fastMediaTypes); + converters.add(converter); + converters.add(fastConverter); + return converters; + } + + + public OkHttp3ClientHttpRequestFactory clientHttpRequestFactory() { + return new OkHttp3ClientHttpRequestFactory(httpClientBuilder()); + } + + public OkHttpClient httpClientBuilder() { + return new OkHttpClient.Builder() + .retryOnConnectionFailure(true) + .connectionPool(this.pool()) + .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) + .readTimeout(readTimeout, TimeUnit.MILLISECONDS) + .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS) + .build(); + } + + public ConnectionPool pool() { + return new ConnectionPool(maxTotal, keepAlive, TimeUnit.MILLISECONDS); + } + + + @Bean + public X509TrustManager x509TrustManager() { + return new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + } + + @Bean + public SSLSocketFactory sslSocketFactory() { + try { + //信任任何链接 + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/ScheduleConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/ScheduleConfig.java new file mode 100644 index 0000000..721428e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/ScheduleConfig.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.scheduling.config.Task; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 定时任务调度 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Configuration +public class ScheduleConfig implements SchedulingConfigurer { + + private ScheduledTaskRegistrar taskRegistrar; + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + this.taskRegistrar = taskRegistrar; + } + + public String destroy() { + List taskList = new ArrayList<>(); + taskList.addAll(taskRegistrar.getCronTaskList()); + taskList.addAll(taskRegistrar.getTriggerTaskList()); + taskList.addAll(taskRegistrar.getFixedDelayTaskList()); + taskList.addAll(taskRegistrar.getFixedRateTaskList()); + + taskRegistrar.destroy(); + + List taskNameList = taskList.stream().map(Task::toString).collect(Collectors.toList()); + return "已关闭 @Scheduled定时任务:" + taskNameList.size() + "个!"; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/SwaggerConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/SwaggerConfig.java new file mode 100644 index 0000000..99e9cb7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/SwaggerConfig.java @@ -0,0 +1,131 @@ +package net.lab1024.sa.base.config; + +import com.google.common.collect.Lists; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.constant.RequestHeaderConst; +import net.lab1024.sa.base.common.swagger.SmartOperationCustomizer; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import org.apache.commons.lang3.StringUtils; +import org.springdoc.core.*; +import org.springdoc.core.customizers.OpenApiBuilderCustomizer; +import org.springdoc.core.customizers.ServerBaseUrlCustomizer; +import org.springdoc.core.providers.JavadocProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; + +import java.util.List; +import java.util.Optional; + +/** + * springdoc-openapi 配置 + * nginx配置前缀时如果需要访问【/swagger-ui/index.html】需添加额外nginx配置 + * location /v3/api-docs/ { + * proxy_pass http://127.0.0.1:1024/v3/api-docs/; + * } + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-03-25 22:54:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Configuration +@Conditional(SystemEnvironmentConfig.class) +public class SwaggerConfig { + /** + * 用于解决/swagger-ui/index.html页面ServersUrl 测试环境部署错误问题 + */ + @Value("${springdoc.swagger-ui.server-base-url}") + private String serverBaseUrl; + + public static final String[] SWAGGER_WHITELIST = { + "/swagger-ui/**", + "/swagger-ui/index.html", + "/swagger-ui.html", + "/swagger-ui.html/**", + "/v3/api-docs", + "/v3/api-docs/**", + "/doc.html", + }; + + @Bean + public OpenAPI api() { + return new OpenAPI() + .components(components()) + .info(new Info() + .title("SmartAdmin 3.X 接口文档") + .contact(new Contact().name("1024创新实验室").email("lab1024@163.com").url("https://1024lab.net")) + .version("v3.X") + .description("**以「高质量代码」为核心,「简洁、高效、安全」**基于 SpringBoot + Sa-Token + Mybatis-Plus 和 Vue3 + Vite5 + Ant Design (同时支持JavaScript和TypeScript双版本) 的快速开发平台。" + + "
**国内首个满足《网络安全》、《数据安全》、三级等保**, 支持登录限制、支持国产接口加解密等安全、支持数据加解密等一系列安全体系的开源项目。" + + "
**我们开源一套漂亮的代码和一套整洁的代码规范**,让大家在这浮躁的代码世界里感受到一股把代码写好的清流!同时又让开发者节省大量的时间,减少加班,快乐工作,保持谦逊,保持学习,热爱代码,更热爱生活!") + ) + .addSecurityItem(new SecurityRequirement().addList(RequestHeaderConst.TOKEN)); + } + + private Components components() { + return new Components() + .addSecuritySchemes(RequestHeaderConst.TOKEN, new SecurityScheme().scheme("Bearer").description("请输入token,格式为[Bearer xxxxxxxx]").type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name(RequestHeaderConst.TOKEN)); + } + + @Bean + public GroupedOpenApi businessApi() { + return GroupedOpenApi.builder() + .group("业务接口") + .pathsToMatch("/**") + .pathsToExclude(SwaggerTagConst.Support.URL_PREFIX + "/**") + .addOperationCustomizer(new SmartOperationCustomizer()) + .build(); + + } + + @Bean + public GroupedOpenApi supportApi() { + return GroupedOpenApi.builder() + .group("支撑接口(Support)") + .pathsToMatch(SwaggerTagConst.Support.URL_PREFIX + "/**") + .addOperationCustomizer(new SmartOperationCustomizer()) + .build(); + } + + /** + * 以下代码可以用于设置 /swagger-ui/index.html 的serverBaseUrl + * 如果使用knife4j则不需要 + * @param openAPI + * @param securityParser + * @param springDocConfigProperties + * @param propertyResolverUtils + * @param openApiBuilderCustomizers + * @param serverBaseUrlCustomizers + * @param javadocProvider + * @return + */ + @Bean + public OpenAPIService openApiBuilder(Optional openAPI, + SecurityService securityParser, + SpringDocConfigProperties springDocConfigProperties, + PropertyResolverUtils propertyResolverUtils, + Optional> openApiBuilderCustomizers, + Optional> serverBaseUrlCustomizers, + Optional javadocProvider) { + List list = Lists.newArrayList(new ServerBaseUrlCustomizer() { + @Override + public String customize(String baseUrl) { + if (StringUtils.isNotBlank(serverBaseUrl)) { + return serverBaseUrl; + } + return baseUrl; + } + }); + return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, + propertyResolverUtils, openApiBuilderCustomizers, Optional.of(list), javadocProvider); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/SystemEnvironmentConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/SystemEnvironmentConfig.java new file mode 100644 index 0000000..caa641d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/SystemEnvironmentConfig.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.config; + +import net.lab1024.sa.base.common.domain.SystemEnvironment; +import net.lab1024.sa.base.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * 系统环境 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/08/13 18:56 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +public class SystemEnvironmentConfig implements Condition { + + @Value("${spring.profiles.active}") + private String systemEnvironment; + + @Value("${project.name}") + private String projectName; + + /** + * 判断是否开启swagger + */ + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + return isDevOrTest(conditionContext); + } + + /** + * 是否为:开发环境和 测试环境 + */ + private boolean isDevOrTest(ConditionContext conditionContext) { + String property = conditionContext.getEnvironment().getProperty("spring.profiles.active"); + return StringUtils.isNotBlank(property) && (SystemEnvironmentEnum.TEST.equalsValue(property) || SystemEnvironmentEnum.DEV.equalsValue(property)); + } + + @Bean("systemEnvironment") + public SystemEnvironment initEnvironment() { + SystemEnvironmentEnum currentEnvironment = SmartEnumUtil.getEnumByValue(systemEnvironment, SystemEnvironmentEnum.class); + if (currentEnvironment == null) { + throw new ExceptionInInitializerError("无法获取当前环境!请在 application.yaml 配置参数:spring.profiles.active"); + } + if (StringUtils.isBlank(projectName)) { + throw new ExceptionInInitializerError("无法获取当前项目名称!请在 application.yaml 配置参数:project.name"); + } + return new SystemEnvironment(currentEnvironment == SystemEnvironmentEnum.PROD, projectName, currentEnvironment); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/TokenConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/TokenConfig.java new file mode 100644 index 0000000..5d82a45 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/TokenConfig.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.base.config; + +import cn.dev33.satoken.config.SaTokenConfig; +import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.Resource; + +/** + * + * 三级等保配置初始化后最低活跃频率全局配置 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/11/24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ + +@Configuration +public class TokenConfig { + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + // 此配置会覆盖 yun-base.yaml 中的配置 + @Resource + public void configSaToken(SaTokenConfig config) { + + config.setActiveTimeout(level3ProtectConfigService.getLoginActiveTimeoutSeconds()); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/UrlConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/config/UrlConfig.java new file mode 100644 index 0000000..0dda491 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/UrlConfig.java @@ -0,0 +1,142 @@ +package net.lab1024.sa.base.config; + +import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.annoation.NoNeedLogin; +import net.lab1024.sa.base.common.domain.RequestUrlVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * url配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Configuration +@Slf4j +public class UrlConfig { + + @Resource + private RequestMappingHandlerMapping requestMappingHandlerMapping; + + /** + * 获取每个方法的请求路径 + */ + @Bean + public Map> methodUrlMap() { + Map> methodUrlMap = Maps.newHashMap(); + //获取url与类和方法的对应信息 + Map map = requestMappingHandlerMapping.getHandlerMethods(); + for (Map.Entry entry : map.entrySet()) { + RequestMappingInfo requestMappingInfo = entry.getKey(); + PathPatternsRequestCondition pathPatternsCondition = requestMappingInfo.getPathPatternsCondition(); + if(pathPatternsCondition == null){ + continue; + } + + Set urls = pathPatternsCondition.getPatternValues(); + if (CollectionUtils.isEmpty(urls)) { + continue; + } + HandlerMethod handlerMethod = entry.getValue(); + methodUrlMap.put(handlerMethod.getMethod(), urls); + } + return methodUrlMap; + } + + /** + * 需要进行url权限校验的方法 + * + * @param methodUrlMap + * @return + */ + @Bean + public List authUrl(Map> methodUrlMap) { + List authUrlList = Lists.newArrayList(); + for (Map.Entry> entry : methodUrlMap.entrySet()) { + Method method = entry.getKey(); + // 忽略权限 + SaIgnore ignore = method.getAnnotation(SaIgnore.class); + if (null != ignore) { + continue; + } + NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class); + if (null != noNeedLogin) { + continue; + } + Set urlSet = entry.getValue(); + List requestUrlList = this.buildRequestUrl(method, urlSet); + authUrlList.addAll(requestUrlList); + } + return authUrlList; + } + + private List buildRequestUrl(Method method, Set urlSet) { + List requestUrlList = Lists.newArrayList(); + if (CollectionUtils.isEmpty(urlSet)) { + return requestUrlList; + } + //url对应的方法名称 + String className = method.getDeclaringClass().getName(); + String methodName = method.getName(); + List list = StrUtil.split(className, "."); + String controllerName = list.get(list.size() - 1); + String name = controllerName + "." + methodName; + //swagger 说明信息 + String methodComment = null; + Operation apiOperation = method.getAnnotation(Operation.class); + if (apiOperation != null) { + methodComment = apiOperation.summary(); + } + for (String url : urlSet) { + RequestUrlVO requestUrlVO = new RequestUrlVO(); + requestUrlVO.setUrl(url); + requestUrlVO.setName(name); + requestUrlVO.setComment(methodComment); + requestUrlList.add(requestUrlVO); + } + return requestUrlList; + } + + + /** + * 获取无需登录可以匿名访问的url信息 + * + * @return + */ + @Bean + public List noNeedLoginUrlList(Map> methodUrlMap) { + List noNeedLoginUrlList = Lists.newArrayList(); + for (Map.Entry> entry : methodUrlMap.entrySet()) { + Method method = entry.getKey(); + NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class); + if (null == noNeedLogin) { + continue; + } + noNeedLoginUrlList.addAll(entry.getValue()); + } + log.info("不需要登录的URL:{}", noNeedLoginUrlList); + return noNeedLoginUrlList; + } + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/config/YamlProcessor.java b/yun-base/src/main/java/net/lab1024/sa/base/config/YamlProcessor.java new file mode 100644 index 0000000..ce834ae --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/config/YamlProcessor.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.config; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.boot.env.YamlPropertySourceLoader; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import java.io.IOException; +import java.util.List; + +/** + * yaml 读取配置 + */ +@Configuration +@Slf4j +@Order(value = 0) +public class YamlProcessor implements EnvironmentPostProcessor { + + private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader(); + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + + String filePath = environment.getProperty("project.log-path"); + if (SmartStringUtil.isNotEmpty(filePath)) { + System.setProperty("project.log-path", filePath); + } + + MutablePropertySources propertySources = environment.getPropertySources(); + this.loadProperty(propertySources); + } + + private void loadProperty(MutablePropertySources propertySources) { + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + try { + Resource[] resources = resolver.getResources("classpath*:yun-*.yaml"); + if (resources.length < 1) { + return; + } + for (Resource resource : resources) { + log.info("初始化系统配置:{}", resource.getFilename()); + List> load = loader.load(resource.getFilename(), resource); + load.forEach(propertySources::addLast); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/constant/CacheKeyConst.java b/yun-base/src/main/java/net/lab1024/sa/base/constant/CacheKeyConst.java new file mode 100644 index 0000000..17aa2d2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/constant/CacheKeyConst.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.constant; + +/** + * 缓存key常量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class CacheKeyConst { + + public static class Dict { + + public static final String DICT_DATA = "dict_data_cache"; + + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/constant/LoginDeviceEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/constant/LoginDeviceEnum.java new file mode 100644 index 0000000..3b503be --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/constant/LoginDeviceEnum.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.constant; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 登录设备类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-11-29 19:48:35 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum LoginDeviceEnum implements BaseEnum { + + PC(1, "电脑端"), + + ANDROID(2, "安卓"), + + APPLE(3, "苹果"), + + H5(4, "H5"), + + WEIXIN_MP(5, "微信小程序"); + + LoginDeviceEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + private Integer value; + private String desc; + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/constant/RedisKeyConst.java b/yun-base/src/main/java/net/lab1024/sa/base/constant/RedisKeyConst.java new file mode 100644 index 0000000..29733c9 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/constant/RedisKeyConst.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.base.constant; + +/** + * redis key 常量类 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class RedisKeyConst { + + public static final String SEPARATOR = ":"; + + public static class Support { + + public static final String FILE_PRIVATE_VO = "file:private:"; + + public static final String SERIAL_NUMBER_LAST_INFO = "serial-number:last-info"; + + public static final String SERIAL_NUMBER = "serial-number:"; + + public static final String CAPTCHA = "captcha:"; + + public static final String LOGIN_VERIFICATION_CODE = "login:verification-code:"; + + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/constant/ReloadConst.java b/yun-base/src/main/java/net/lab1024/sa/base/constant/ReloadConst.java new file mode 100644 index 0000000..bcdfc38 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/constant/ReloadConst.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.base.constant; + +/** + * reload 项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class ReloadConst { + + public static final String CONFIG_RELOAD = "system_config"; + + public static final String CACHE_SERVICE = "cache_service"; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/constant/SwaggerTagConst.java b/yun-base/src/main/java/net/lab1024/sa/base/constant/SwaggerTagConst.java new file mode 100644 index 0000000..fa30161 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/constant/SwaggerTagConst.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.constant; + +/** + * swagger + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SwaggerTagConst { + + public static class Support { + + public static final String URL_PREFIX = "/support"; + + public static final String CACHE = "业务支撑-缓存"; + + public static final String CAPTCHA = "业务支撑-验证码"; + + public static final String OPERATE_LOG = "业务支撑-用户操作记录"; + + public static final String LOGIN_LOG = "业务支撑-登录日志"; + + public static final String RELOAD = "业务支撑-reload"; + + public static final String SERIAL_NUMBER = "业务支撑-id生成器"; + + public static final String HEART_BEAT = "业务支撑-服务心跳"; + + public static final String FILE = "业务支撑-文件服务"; + + public static final String CONFIG = "业务支撑-系统参数"; + + public static final String DATA_TRACER = "业务支撑-数据变动记录"; + + public static final String DICT = "业务支撑-数据字典"; + + public static final String CODE_GENERATOR = "业务支撑-代码生成"; + + public static final String CHANGE_LOG = "业务支撑-更新日志"; + + public static final String HELP_DOC = "业务支撑-帮助文档"; + + public static final String FEEDBACK = "业务支撑-意见反馈"; + + public static final String TABLE_COLUMN = "业务支撑-列自定义"; + + public static final String PROTECT = "业务支撑-网络安全"; + + public static final String DATA_MASKING = "业务支撑-数据脱敏"; + + public static final String JOB = "业务支撑-定时任务"; + + public static final String MESSAGE = "业务支撑-消息"; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/handler/GlobalExceptionHandler.java b/yun-base/src/main/java/net/lab1024/sa/base/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..3bafe3e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/handler/GlobalExceptionHandler.java @@ -0,0 +1,130 @@ +package net.lab1024.sa.base.handler; + +import cn.dev33.satoken.exception.NotPermissionException; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.code.SystemErrorCode; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.SystemEnvironment; +import net.lab1024.sa.base.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.base.common.exception.BusinessException; +import org.springframework.beans.TypeMismatchException; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 全局异常拦截 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020/8/25 21:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@ControllerAdvice +public class GlobalExceptionHandler { + + @Resource + private SystemEnvironment systemEnvironment; + + /** + * json 格式错误 缺少请求体 + */ + @ResponseBody + @ExceptionHandler({HttpMessageNotReadableException.class}) + public ResponseDTO jsonFormatExceptionHandler(Exception e) { + if (!systemEnvironment.isProd()) { + log.error("全局JSON格式错误异常,URL:{}", getCurrentRequestUrl(), e); + } + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "参数JSON格式错误"); + } + + /** + * json 格式错误 缺少请求体 + */ + @ResponseBody + @ExceptionHandler({TypeMismatchException.class, BindException.class}) + public ResponseDTO paramExceptionHandler(Exception e) { + if (e instanceof BindException) { + if (e instanceof MethodArgumentNotValidException) { + List fieldErrors = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors(); + List msgList = fieldErrors.stream().map(FieldError::getDefaultMessage).collect(Collectors.toList()); + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, String.join(",", msgList)); + } + + List fieldErrors = ((BindException) e).getFieldErrors(); + List error = fieldErrors.stream().map(field -> field.getField() + ":" + field.getRejectedValue()).collect(Collectors.toList()); + String errorMsg = UserErrorCode.PARAM_ERROR.getMsg() + ":" + error; + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, errorMsg); + } + return ResponseDTO.error(UserErrorCode.PARAM_ERROR); + } + + /** + * sa-token 权限异常处理 + * + * @param e 权限异常 + * @return 错误结果 + */ + @ResponseBody + @ExceptionHandler(NotPermissionException.class) + public ResponseDTO permissionException(NotPermissionException e) { + // 开发环境 方便调试 + if (SystemEnvironmentEnum.PROD != systemEnvironment.getCurrentEnvironment()) { + return ResponseDTO.error(UserErrorCode.NO_PERMISSION, e.getMessage()); + } + return ResponseDTO.error(UserErrorCode.NO_PERMISSION); + } + + + /** + * 业务异常 + */ + @ResponseBody + @ExceptionHandler(BusinessException.class) + public ResponseDTO businessExceptionHandler(BusinessException e) { + if (!systemEnvironment.isProd()) { + log.error("全局业务异常,URL:{}", getCurrentRequestUrl(), e); + } + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, e.getMessage()); + } + + /** + * 其他全部异常 + * + * @param e 全局异常 + * @return 错误结果 + */ + @ResponseBody + @ExceptionHandler(Throwable.class) + public ResponseDTO errorHandler(Throwable e) { + log.error("捕获全局异常,URL:{}", getCurrentRequestUrl(), e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, systemEnvironment.isProd() ? null : e.toString()); + } + + /** + * 获取当前请求url + */ + private String getCurrentRequestUrl() { + RequestAttributes request = RequestContextHolder.getRequestAttributes(); + if (null == request) { + return null; + } + ServletRequestAttributes servletRequest = (ServletRequestAttributes) request; + return servletRequest.getRequest().getRequestURI(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/handler/MybatisPlusFillHandler.java b/yun-base/src/main/java/net/lab1024/sa/base/handler/MybatisPlusFillHandler.java new file mode 100644 index 0000000..372ff75 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/handler/MybatisPlusFillHandler.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.base.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * Mybatis Plus 插入或者更新时指定字段设置值 + * + * @author zhoumingfa + */ +@Component +@Slf4j +public class MybatisPlusFillHandler implements MetaObjectHandler { + + public static final String CREATE_TIME = "createTime"; + + public static final String UPDATE_TIME = "updateTime"; + + @Override + public void insertFill(MetaObject metaObject) { + if (metaObject.hasSetter(CREATE_TIME)) { + this.fillStrategy(metaObject, CREATE_TIME, LocalDateTime.now()); + } + if (metaObject.hasSetter(UPDATE_TIME)) { + this.fillStrategy(metaObject, UPDATE_TIME, LocalDateTime.now()); + } + } + + @Override + public void updateFill(MetaObject metaObject) { + if (metaObject.hasSetter(UPDATE_TIME)) { + this.fillStrategy(metaObject, UPDATE_TIME, LocalDateTime.now()); + } + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/listener/Ip2RegionListener.java b/yun-base/src/main/java/net/lab1024/sa/base/listener/Ip2RegionListener.java new file mode 100644 index 0000000..0055d15 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/listener/Ip2RegionListener.java @@ -0,0 +1,76 @@ +package net.lab1024.sa.base.listener; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartIpUtil; +import org.apache.commons.io.FileUtils; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.boot.context.logging.LoggingApplicationListener; +import org.springframework.context.ApplicationListener; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.io.ClassPathResource; + +import java.io.File; +import java.io.IOException; + +/** + * 初初始化ip工具类 + * + * @Author 1024创新实验室: zhuoda + * @Date 2023-09-03 23:45:26 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Order(value = LoggingApplicationListener.DEFAULT_ORDER) +@Slf4j +public class Ip2RegionListener implements ApplicationListener { + + private static final String IP_FILE_NAME = "ip2region.xdb"; + + private static final String LOG_DIRECTORY = "project.log-directory"; + + @Override + public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEvent) { + + ConfigurableEnvironment environment = applicationEvent.getEnvironment(); + String logDirectoryPath = environment.getProperty(LOG_DIRECTORY); + if (logDirectoryPath == null) { + throw new ExceptionInInitializerError("环境变量为空:" + LOG_DIRECTORY); + } + System.setProperty(LOG_DIRECTORY, logDirectoryPath); + + // 1、从jar中的ip2region.xdb文件复制到服务器目录中 + File logDirectoryFile = new File(logDirectoryPath); + if (!logDirectoryFile.exists()) { + logDirectoryFile.mkdirs(); + } + + String tempFilePath = null; + if (logDirectoryPath.endsWith("/")) { + tempFilePath = logDirectoryPath + IP_FILE_NAME; + } else { + tempFilePath = logDirectoryPath + "/" + IP_FILE_NAME; + } + + File tempFile = new File(tempFilePath); + try { + FileUtils.copyInputStreamToFile(new ClassPathResource(IP_FILE_NAME).getInputStream(), tempFile); + + // 2、初始化 + SmartIpUtil.init(tempFilePath); + + + } catch (IOException e) { + log.error("无法复制ip数据文件 ip2region.xdb", e); + throw new ExceptionInInitializerError("无法复制ip数据文件"); + } finally { + if (tempFile.exists()) { + tempFile.delete(); + } + } + + } + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/listener/LogVariableListener.java b/yun-base/src/main/java/net/lab1024/sa/base/listener/LogVariableListener.java new file mode 100644 index 0000000..407445c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/listener/LogVariableListener.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.listener; + +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.boot.context.logging.LoggingApplicationListener; +import org.springframework.context.ApplicationListener; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.ConfigurableEnvironment; + +/** + * 将application.yam l中的日志路径变量:project.log-path注入到 log4j2.xml + * + * @Author 1024创新实验室: zhuoda + * @Date 2023-09-03 23:45:26 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Order(value = LoggingApplicationListener.DEFAULT_ORDER - 1) +public class LogVariableListener implements ApplicationListener { + + private static final String LOG_DIRECTORY = "project.log-directory"; + + @Override + public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEvent) { + + ConfigurableEnvironment environment = applicationEvent.getEnvironment(); + String filePath = environment.getProperty(LOG_DIRECTORY); + if (filePath != null) { + System.setProperty(LOG_DIRECTORY, filePath); + } + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/listener/WebServerListener.java b/yun-base/src/main/java/net/lab1024/sa/base/listener/WebServerListener.java new file mode 100644 index 0000000..c248c7d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/listener/WebServerListener.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.base.listener; + +import cn.hutool.core.net.NetUtil; +import cn.hutool.core.util.URLUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.code.ErrorCodeRegister; +import net.lab1024.sa.base.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * 启动监听器 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-23 23:45:26 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Component +@Order(value = 1024) +public class WebServerListener implements ApplicationListener { + + @Value("${reload.interval-seconds}") + private Integer intervalSeconds; + + @Override + public void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) { + WebServerApplicationContext context = webServerInitializedEvent.getApplicationContext(); + // 初始化reload + initReload(context); + // 项目信息 + showProjectMessage(webServerInitializedEvent); + } + + /** + * 显示项目信息 + */ + private void showProjectMessage(WebServerInitializedEvent webServerInitializedEvent) { + WebServerApplicationContext context = webServerInitializedEvent.getApplicationContext(); + Environment env = context.getEnvironment(); + + //获取服务信息 + String ip = NetUtil.getLocalhost().getHostAddress(); + Integer port = webServerInitializedEvent.getWebServer().getPort(); + String contextPath = env.getProperty("server.servlet.context-path"); + if (contextPath == null) { + contextPath = ""; + } + String profile = env.getProperty("spring.profiles.active"); + SystemEnvironmentEnum environmentEnum = SmartEnumUtil.getEnumByValue(profile, SystemEnvironmentEnum.class); + String projectName = env.getProperty("project.name"); + //拼接服务地址 + String title = String.format("-------------【%s】 服务已成功启动 (%s started successfully)-------------", projectName, projectName); + + // 初始化状态码 + int codeCount = ErrorCodeRegister.initialize(); + String localhostUrl = URLUtil.normalize(String.format("http://localhost:%d%s", port, contextPath), false, true); + String externalUrl = URLUtil.normalize(String.format("http://%s:%d%s", ip, port, contextPath), false, true); + String swaggerUrl = URLUtil.normalize(String.format("http://localhost:%d%s/swagger-ui/index.html", port, contextPath), false, true); + String knife4jUrl = URLUtil.normalize(String.format("http://localhost:%d%s/doc.html", port, contextPath), false, true); + log.warn("\n{}\n" + + "\t当前启动环境:\t{} , {}" + + "\n\t返回码初始化:\t完成{}个返回码初始化" + + "\n\t服务本机地址:\t{}" + + "\n\t服务外网地址:\t{}" + + "\n\tSwagger地址:\t{}" + + "\n\tknife4j地址:\t{}" + + "\n-------------------------------------------------------------------------------------\n", + title, profile, environmentEnum.getDesc(), codeCount, localhostUrl, externalUrl, swaggerUrl, knife4jUrl); + } + + /** + * 初始化reload + */ + private void initReload(WebServerApplicationContext applicationContext) { +// 将applicationContext转换为ConfigurableApplicationContext +// ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext; +// +// +// //获取BeanFactory +// DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory(); +// +// //动态注册bean +// SmartReloadManager reloadManager = new SmartReloadManager(applicationContext.getBean(ReloadCommand.class), intervalSeconds); +// defaultListableBeanFactory.registerSingleton("smartReloadManager", reloadManager); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice.java new file mode 100644 index 0000000..f93908b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.base.module.support.apiencrypt.advice; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiDecrypt; +import net.lab1024.sa.base.module.support.apiencrypt.domain.ApiEncryptForm; +import net.lab1024.sa.base.module.support.apiencrypt.service.ApiEncryptService; +import org.apache.commons.io.IOUtils; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter; + +import javax.annotation.Resource; +import java.io.InputStream; +import java.lang.reflect.Type; + +/** + * 解密 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Slf4j +@ControllerAdvice +public class DecryptRequestAdvice extends RequestBodyAdviceAdapter { + + private static final String ENCODING = "UTF-8"; + + @Resource + private ApiEncryptService apiEncryptService; + + @Resource + private ObjectMapper objectMapper; + + @Override + public boolean supports(MethodParameter methodParameter, Type targetType, Class> converterType) { + return methodParameter.hasMethodAnnotation(ApiDecrypt.class) || methodParameter.hasParameterAnnotation(ApiDecrypt.class) || methodParameter.getContainingClass().isAnnotationPresent(ApiDecrypt.class); + } + + @Override + public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) { + try { + String bodyStr = IOUtils.toString(inputMessage.getBody(), ENCODING); + ApiEncryptForm apiEncryptForm = objectMapper.readValue(bodyStr, ApiEncryptForm.class); + if (SmartStringUtil.isEmpty(apiEncryptForm.getEncryptData())) { + return inputMessage; + } + String decrypt = apiEncryptService.decrypt(apiEncryptForm.getEncryptData()); + return new DecryptHttpInputMessage(inputMessage.getHeaders(), IOUtils.toInputStream(decrypt, ENCODING)); + } catch (Exception e) { + log.error("", e); + return inputMessage; + } + } + + @Override + public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) { + return body; + } + + @Override + public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) { + return body; + } + + static class DecryptHttpInputMessage implements HttpInputMessage { + private final HttpHeaders headers; + + private final InputStream body; + + public DecryptHttpInputMessage(HttpHeaders headers, InputStream body) { + this.headers = headers; + this.body = body; + } + + @Override + public InputStream getBody() { + return body; + } + + @Override + public HttpHeaders getHeaders() { + return headers; + } + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/advice/EncryptResponseAdvice.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/advice/EncryptResponseAdvice.java new file mode 100644 index 0000000..0787609 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/advice/EncryptResponseAdvice.java @@ -0,0 +1,63 @@ +package net.lab1024.sa.base.module.support.apiencrypt.advice; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.enumeration.DataTypeEnum; +import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiEncrypt; +import net.lab1024.sa.base.module.support.apiencrypt.service.ApiEncryptService; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +import javax.annotation.Resource; + +/** + * 加密 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/24 09:52:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + + +@Slf4j +@ControllerAdvice +public class EncryptResponseAdvice implements ResponseBodyAdvice> { + + @Resource + private ApiEncryptService apiEncryptService; + + @Resource + private ObjectMapper objectMapper; + + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + return returnType.hasMethodAnnotation(ApiEncrypt.class) || returnType.getContainingClass().isAnnotationPresent(ApiEncrypt.class); + } + + @Override + public ResponseDTO beforeBodyWrite(ResponseDTO body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + if (body == null || body.getData() == null) { + return body; + } + + try { + String encrypt = apiEncryptService.encrypt(objectMapper.writeValueAsString(body.getData())); + body.setData(encrypt); + body.setDataType(DataTypeEnum.ENCRYPT.getValue()); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + return body; + } +} + + diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiDecrypt.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiDecrypt.java new file mode 100644 index 0000000..bedfc90 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiDecrypt.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.apiencrypt.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 解密注解 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface ApiDecrypt { +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiEncrypt.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiEncrypt.java new file mode 100644 index 0000000..4b6950d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiEncrypt.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.apiencrypt.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 加密注解 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface ApiEncrypt { +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/domain/ApiEncryptForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/domain/ApiEncryptForm.java new file mode 100644 index 0000000..31e3aee --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/domain/ApiEncryptForm.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.apiencrypt.domain; + +import lombok.Data; + +/** + * 加密数据的表单 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + + +@Data +public class ApiEncryptForm { + + private String encryptData; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptService.java new file mode 100644 index 0000000..6c65708 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptService.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.module.support.apiencrypt.service; + +/** + * 接口加密、解密 Service + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public interface ApiEncryptService { + + /** + * 解密 + * @param data + * @return + */ + String decrypt(String data); + + /** + * 加密 + * + * @param data + * @return + */ + String encrypt(String data); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceAesImpl.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceAesImpl.java new file mode 100644 index 0000000..3e7ae91 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceAesImpl.java @@ -0,0 +1,114 @@ +package net.lab1024.sa.base.module.support.apiencrypt.service; + +import cn.hutool.crypto.symmetric.AES; +import cn.hutool.crypto.symmetric.SM4; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.constant.StringConst; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.springframework.stereotype.Service; + +import java.io.UnsupportedEncodingException; +import java.security.Security; +import java.util.Base64; + +/** + * AES 加密和解密 + * 1、AES加密算法支持三种密钥长度:128位、192位和256位,这里选择128位 + * 2、AES 要求秘钥为 128bit,转化字节为 16个字节; + * 3、js前端使用 UCS-2 或者 UTF-16 编码,字母、数字、特殊符号等 占用1个字节; + * 4、所以:秘钥Key 组成为:字母、数字、特殊符号 一共16个即可 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Slf4j +public class ApiEncryptServiceAesImpl implements ApiEncryptService { + + private static final String CHARSET = "UTF-8"; + + private static final String AES_KEY = "1024lab__1024lab"; + + static { + Security.addProvider(new BouncyCastleProvider()); + } + + @Override + public String encrypt(String data) { + try { + // AES 加密 并转为 base64 + AES aes = new AES(hexToBytes(stringToHex(AES_KEY))); + return aes.encryptBase64(data); + + + } catch (Exception e) { + log.error(e.getMessage(), e); + return StringConst.EMPTY; + } + } + + @Override + public String decrypt(String data) { + try { + // 第一步: Base64 解码 + byte[] base64Decode = Base64.getDecoder().decode(data); + + // 第二步: AES 解密 + AES aes = new AES(hexToBytes(stringToHex(AES_KEY))); + byte[] decryptedBytes = aes.decrypt(base64Decode); + return new String(decryptedBytes, CHARSET); + + } catch (Exception e) { + log.error(e.getMessage(), e); + return StringConst.EMPTY; + } + } + + /** + * 16 进制串转字节数组 + * + * @param hex 16进制字符串 + * @return byte数组 + */ + public static byte[] hexToBytes(String hex) { + int length = hex.length(); + byte[] result; + if (length % 2 == 1) { + length++; + result = new byte[(length / 2)]; + hex = "0" + hex; + } else { + result = new byte[(length / 2)]; + } + int j = 0; + for (int i = 0; i < length; i += 2) { + result[j] = hexToByte(hex.substring(i, i + 2)); + j++; + } + return result; + } + + public static String stringToHex(String input) { + char[] chars = input.toCharArray(); + StringBuilder hex = new StringBuilder(); + for (char c : chars) { + hex.append(Integer.toHexString((int) c)); + } + return hex.toString(); + } + + /** + * 16 进制字符转字节 + * + * @param hex 16进制字符 0x00到0xFF + * @return byte + */ + private static byte hexToByte(String hex) { + return (byte) Integer.parseInt(hex, 16); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceSmImpl.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceSmImpl.java new file mode 100644 index 0000000..d8d63fa --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceSmImpl.java @@ -0,0 +1,118 @@ +package net.lab1024.sa.base.module.support.apiencrypt.service; + +import cn.hutool.crypto.symmetric.SM4; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.constant.StringConst; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.springframework.stereotype.Service; + +import java.security.Security; +import java.util.Base64; + +/** + * 国产 SM4 加密 和 解密 + * 1、国密SM4 要求秘钥为 128bit,转化字节为 16个字节; + * 2、js前端使用 UCS-2 或者 UTF-16 编码,字母、数字、特殊符号等 占用1个字节; + * 3、java中 每个 字母数字 也是占用1个字节; + * 4、所以:前端和后端的 秘钥Key 组成为:字母、数字、特殊符号 一共16个即可 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/21 11:41:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Slf4j +@Service +public class ApiEncryptServiceSmImpl implements ApiEncryptService { + + private static final String CHARSET = "UTF-8"; + private static final String SM4_KEY = "1024lab__1024lab"; + + static { + Security.addProvider(new BouncyCastleProvider()); + } + + + @Override + public String encrypt(String data) { + try { + + // 第一步: SM4 加密 + SM4 sm4 = new SM4(hexToBytes(stringToHex(SM4_KEY))); + String encryptHex = sm4.encryptHex(data); + + // 第二步: Base64 编码 + return new String(Base64.getEncoder().encode(encryptHex.getBytes(CHARSET)), CHARSET); + + } catch (Exception e) { + log.error(e.getMessage(), e); + return StringConst.EMPTY; + } + } + + + @Override + public String decrypt(String data) { + try { + + // 第一步: Base64 解码 + byte[] base64Decode = Base64.getDecoder().decode(data); + + // 第二步: SM4 解密 + SM4 sm4 = new SM4(hexToBytes(stringToHex(SM4_KEY))); + return sm4.decryptStr(new String(base64Decode)); + + } catch (Exception e) { + log.error(e.getMessage(), e); + return StringConst.EMPTY; + } + } + + + public static String stringToHex(String input) { + char[] chars = input.toCharArray(); + StringBuilder hex = new StringBuilder(); + for (char c : chars) { + hex.append(Integer.toHexString((int) c)); + } + return hex.toString(); + } + + + /** + * 16 进制串转字节数组 + * + * @param hex 16进制字符串 + * @return byte数组 + */ + public static byte[] hexToBytes(String hex) { + int length = hex.length(); + byte[] result; + if (length % 2 == 1) { + length++; + result = new byte[(length / 2)]; + hex = "0" + hex; + } else { + result = new byte[(length / 2)]; + } + int j = 0; + for (int i = 0; i < length; i += 2) { + result[j] = hexToByte(hex.substring(i, i + 2)); + j++; + } + return result; + } + + /** + * 16 进制字符转字节 + * + * @param hex 16进制字符 0x00到0xFF + * @return byte + */ + private static byte hexToByte(String hex) { + return (byte) Integer.parseInt(hex, 16); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/CacheService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/CacheService.java new file mode 100644 index 0000000..ef6255c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/CacheService.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.base.module.support.cache; + +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 缓存服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/11 20:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public interface CacheService { + + /** + * 获取所有缓存名称 + */ + List cacheNames(); + + /** + * 某个缓存下的所有 key + */ + List cacheKey(String cacheName); + + /** + * 移除某个 key + */ + void removeCache(String cacheName); + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/CaffeineCacheServiceImpl.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/CaffeineCacheServiceImpl.java new file mode 100644 index 0000000..4a41121 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/CaffeineCacheServiceImpl.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.base.module.support.cache; + +import com.google.common.collect.Lists; +import net.lab1024.sa.base.constant.ReloadConst; +import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload; +import org.springframework.cache.caffeine.CaffeineCache; +import org.springframework.cache.caffeine.CaffeineCacheManager; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * caffeine 缓存实现 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/11 20:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class CaffeineCacheServiceImpl implements CacheService { + + @Resource + private CaffeineCacheManager caffeineCacheManager; + + /** + * 获取所有缓存名称 + */ + @Override + public List cacheNames() { + return Lists.newArrayList(caffeineCacheManager.getCacheNames()); + } + + /** + * 某个缓存下的所有 key + */ + @Override + public List cacheKey(String cacheName) { + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); + if (cache == null) { + return Lists.newArrayList(); + } + Set cacheKey = cache.getNativeCache().asMap().keySet(); + return cacheKey.stream().map(e -> e.toString()).collect(Collectors.toList()); + } + + /** + * 移除某个 key + */ + @Override + public void removeCache(String cacheName) { + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); + if (cache != null) { + cache.clear(); + } + } + + @SmartReload(ReloadConst.CACHE_SERVICE) + public void clearAllCache() { + Collection cacheNames = caffeineCacheManager.getCacheNames(); + for (String name : cacheNames) { + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(name); + if (cache != null) { + cache.clear(); + } + } + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/RedisCacheServiceImpl.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/RedisCacheServiceImpl.java new file mode 100644 index 0000000..dc6391f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/cache/RedisCacheServiceImpl.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.base.module.support.cache; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import net.lab1024.sa.base.constant.ReloadConst; +import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload; +import org.springframework.data.redis.cache.RedisCache; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * redis 缓存实现 + * + * @author zhoumingfa + * @date 2025/3/28 + */ +public class RedisCacheServiceImpl implements CacheService { + + @Resource + private RedisCacheManager redisCacheManager; + + @Resource + private RedisConnectionFactory redisConnectionFactory; + + /** + * 获取所有缓存名称 + */ + @Override + public List cacheNames() { + return Lists.newArrayList(redisCacheManager.getCacheNames()); + } + + /** + * 某个缓存下的所有 key + */ + @Override + public List cacheKey(String cacheName) { + RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName); + if (cache == null) { + return Lists.newArrayList(); + } + // 获取 Redis 连接 + RedisConnection connection = redisConnectionFactory.getConnection(); + // 根据指定的 key 模式获取所有匹配的键 + Set keys = connection.keyCommands().keys((cacheName + ":*").getBytes()); + + if (keys != null) { + return keys.stream().map(key -> { + String redisKey = StrUtil.str(key, "utf-8"); + // 从 Redis 键中提取出最后一个冒号后面的字符串作为真正的键 + return redisKey.substring(redisKey.lastIndexOf(":") + 1); + }).collect(Collectors.toList()); + } + connection.close(); + return Lists.newArrayList(cacheName); + } + + /** + * 移除某个 key + */ + @Override + public void removeCache(String cacheName) { + RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName); + if (cache != null) { + cache.clear(); + } + } + + @SmartReload(ReloadConst.CACHE_SERVICE) + public void clearAllCache() { + Collection cacheNames = redisCacheManager.getCacheNames(); + for (String name : cacheNames) { + RedisCache cache = (RedisCache) redisCacheManager.getCache(name); + if (cache != null) { + cache.clear(); + } + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/CaptchaController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/CaptchaController.java new file mode 100644 index 0000000..b98074f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/CaptchaController.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.captcha; + + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.captcha.domain.CaptchaVO; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 图形验证码业务 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.CAPTCHA) +@RestController +public class CaptchaController extends SupportBaseController { + + @Resource + private CaptchaService captchaService; + + @Operation(summary = "获取图形验证码 @author 胡克") + @GetMapping("/captcha") + public ResponseDTO generateCaptcha() { + return ResponseDTO.ok(captchaService.generateCaptcha()); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/CaptchaService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/CaptchaService.java new file mode 100644 index 0000000..314107f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/CaptchaService.java @@ -0,0 +1,110 @@ +package net.lab1024.sa.base.module.support.captcha; + +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.core.img.ImgUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.SystemEnvironment; +import net.lab1024.sa.base.constant.RedisKeyConst; +import net.lab1024.sa.base.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.base.module.support.captcha.domain.CaptchaVO; +import net.lab1024.sa.base.module.support.redis.RedisService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.awt.*; +import java.util.Objects; + +/** + * 图形验证码 服务 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/8/31 20:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class CaptchaService { + + /** + * 过期时间:65秒 + */ + private static final long EXPIRE_SECOND = 65L; + + @Resource + private SystemEnvironment systemEnvironment; + + @Resource + private RedisService redisService; + + /** + * 生成图形验证码 + * 默认 1 分钟有效期 + */ + public CaptchaVO generateCaptcha() { + + //生成四位验证码 + String captchaText = RandomUtil.randomNumbers(4); + + //定义图形验证码的长、宽、验证码位数、干扰线数量 + LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(125, 43, 4, 80); + + //设置背景颜色 + lineCaptcha.setBackground(new Color(230, 244, 255)); + + //生成图片 + Image image = lineCaptcha.createImage(captchaText); + + //转为base64 + String base64Code = ImgUtil.toBase64(image, "jpg"); + + /* + * 返回验证码对象 + * 图片 base64格式 + */ + // uuid 唯一标识 + String uuid = IdUtil.fastSimpleUUID(); + + CaptchaVO captchaVO = new CaptchaVO(); + captchaVO.setCaptchaUuid(uuid); + captchaVO.setCaptchaBase64Image("data:image/png;base64," + base64Code); + captchaVO.setExpireSeconds(EXPIRE_SECOND); + if (!systemEnvironment.isProd()) { + captchaVO.setCaptchaText(captchaText); + } + String redisCaptchaKey = redisService.generateRedisKey(RedisKeyConst.Support.CAPTCHA, uuid); + redisService.set(redisCaptchaKey, captchaText, EXPIRE_SECOND); + return captchaVO; + } + + /** + * 校验图形验证码 + */ + public ResponseDTO checkCaptcha(CaptchaForm captchaForm) { + if (StringUtils.isBlank(captchaForm.getCaptchaUuid()) || StringUtils.isBlank(captchaForm.getCaptchaCode())) { + return ResponseDTO.userErrorParam("请输入正确验证码"); + } + /* + * 1、校验redis里的验证码 + * 2、校验成功后,删除redis + */ + String redisCaptchaKey = redisService.generateRedisKey(RedisKeyConst.Support.CAPTCHA, captchaForm.getCaptchaUuid()); + String redisCaptchaCode = redisService.get(redisCaptchaKey); + if (StringUtils.isBlank(redisCaptchaCode)) { + return ResponseDTO.userErrorParam("验证码已过期,请刷新重试"); + } + if (!Objects.equals(redisCaptchaCode, captchaForm.getCaptchaCode())) { + return ResponseDTO.userErrorParam("验证码错误,请输入正确的验证码"); + } + // 删除已使用的验证码 + redisService.delete(redisCaptchaKey); + return ResponseDTO.ok(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/domain/CaptchaForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/domain/CaptchaForm.java new file mode 100644 index 0000000..0ecec9f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/domain/CaptchaForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.captcha.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 图形验证码 表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CaptchaForm { + + @Schema(description = "验证码") + @NotBlank(message = "验证码不能为空") + private String captchaCode; + + @Schema(description = "验证码uuid标识") + @NotBlank(message = "验证码uuid标识不能为空") + private String captchaUuid; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/domain/CaptchaVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/domain/CaptchaVO.java new file mode 100644 index 0000000..a198a90 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/captcha/domain/CaptchaVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.base.module.support.captcha.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 图形验证码 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/8/31 20:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CaptchaVO { + + @Schema(description = "验证码唯一标识") + private String captchaUuid; + + @Schema(description = "验证码图片内容-生产环境无效") + private String captchaText; + + @Schema(description = "验证码Base64图片") + private String captchaBase64Image; + + @Schema(description = "过期时间(秒)") + private Long expireSeconds; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/constant/ChangeLogTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/constant/ChangeLogTypeEnum.java new file mode 100644 index 0000000..be53584 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/constant/ChangeLogTypeEnum.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.module.support.changelog.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] + * + * @Author 卓大 + * @Date 2022-09-26T14:53:50 + * @Copyright 1024创新实验室 + */ + +@AllArgsConstructor +@Getter +public enum ChangeLogTypeEnum implements BaseEnum { + + /** + * 重大更新 + */ + MAJOR_UPDATE(1, "重大更新"), + + /** + * 功能更新 + */ + FUNCTION_UPDATE(2, "功能更新"), + + /** + * Bug修复 + */ + BUG_FIX(3, "Bug修复"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/controller/ChangeLogController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/controller/ChangeLogController.java new file mode 100644 index 0000000..48a60bb --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/controller/ChangeLogController.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.base.module.support.changelog.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogQueryForm; +import net.lab1024.sa.base.module.support.changelog.domain.vo.ChangeLogVO; +import net.lab1024.sa.base.module.support.changelog.service.ChangeLogService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 系统更新日志 Controller + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@RestController +@Tag(name = SwaggerTagConst.Support.CHANGE_LOG) +public class ChangeLogController extends SupportBaseController { + + @Resource + private ChangeLogService changeLogService; + + @Operation(summary = "分页查询 @author 卓大") + @PostMapping("/changeLog/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid ChangeLogQueryForm queryForm) { + return ResponseDTO.ok(changeLogService.queryPage(queryForm)); + } + + + @Operation(summary = "变更内容详情 @author 卓大") + @GetMapping("/changeLog/getDetail/{changeLogId}") + public ResponseDTO getDetail(@PathVariable Long changeLogId) { + return ResponseDTO.ok(changeLogService.getById(changeLogId)); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/dao/ChangeLogDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/dao/ChangeLogDao.java new file mode 100644 index 0000000..09f72cc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/dao/ChangeLogDao.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.module.support.changelog.dao; + +import java.util.List; + +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogQueryForm; +import net.lab1024.sa.base.module.support.changelog.domain.vo.ChangeLogVO; +import net.lab1024.sa.base.module.support.changelog.domain.entity.ChangeLogEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 系统更新日志 Dao + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Mapper +public interface ChangeLogDao extends BaseMapper { + + /** + * 分页 查询 + * + */ + List queryPage(Page page, @Param("queryForm") ChangeLogQueryForm queryForm); + + /** + * 根据版本查询 ChangeLog + * + */ + ChangeLogEntity selectByVersion(@Param("version") String version); + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/entity/ChangeLogEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/entity/ChangeLogEntity.java new file mode 100644 index 0000000..3361a8d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/entity/ChangeLogEntity.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.base.module.support.changelog.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDate; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 系统更新日志 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +@TableName("t_change_log") +public class ChangeLogEntity { + + /** + * 更新日志id + */ + @TableId(type = IdType.AUTO) + private Long changeLogId; + + /** + * 版本 + */ + private String updateVersion; + + /** + * 更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] + */ + private Integer type; + + /** + * 发布人 + */ + private String publishAuthor; + + /** + * 发布日期 + */ + private LocalDate publicDate; + + /** + * 更新内容 + */ + private String content; + + /** + * 跳转链接 + */ + private String link; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogAddForm.java new file mode 100644 index 0000000..239333c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogAddForm.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.module.support.changelog.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDate; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.changelog.constant.ChangeLogTypeEnum; + +/** + * 系统更新日志 新建表单 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogAddForm { + + @Schema(description = "版本", required = true) + @NotBlank(message = "版本 不能为空") + private String updateVersion; + + @SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + @CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误", required = true) + private Integer type; + + @Schema(description = "发布人", required = true) + @NotBlank(message = "发布人 不能为空") + private String publishAuthor; + + @Schema(description = "发布日期", required = true) + @NotNull(message = "发布日期 不能为空") + private LocalDate publicDate; + + @Schema(description = "更新内容", required = true) + @NotBlank(message = "更新内容 不能为空") + private String content; + + @Schema(description = "跳转链接") + private String link; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogQueryForm.java new file mode 100644 index 0000000..699ff5d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogQueryForm.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.base.module.support.changelog.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.changelog.constant.ChangeLogTypeEnum; + +import java.time.LocalDate; + +/** + * 系统更新日志 查询 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogQueryForm extends PageParam{ + + @SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + @CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误") + private Integer type; + + @Schema(description = "关键字") + private String keyword; + + @Schema(description = "发布日期") + private LocalDate publicDateBegin; + + @Schema(description = "发布日期") + private LocalDate publicDateEnd; + + @Schema(description = "创建时间") + private LocalDate createTime; + + @Schema(description = "跳转链接") + private String link; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogUpdateForm.java new file mode 100644 index 0000000..13d48ce --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogUpdateForm.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.base.module.support.changelog.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDate; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.changelog.constant.ChangeLogTypeEnum; + +/** + * 系统更新日志 更新表单 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogUpdateForm { + + @Schema(description = "更新日志id", required = true) + @NotNull(message = "更新日志id 不能为空") + private Long changeLogId; + + @Schema(description = "版本", required = true) + @NotBlank(message = "版本 不能为空") + private String updateVersion; + + @SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + @CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误", required = true) + private Integer type; + + @Schema(description = "发布人", required = true) + @NotBlank(message = "发布人 不能为空") + private String publishAuthor; + + @Schema(description = "发布日期", required = true) + @NotNull(message = "发布日期 不能为空") + private LocalDate publicDate; + + @Schema(description = "更新内容", required = true) + @NotBlank(message = "更新内容 不能为空") + private String content; + + @Schema(description = "跳转链接") + private String link; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/vo/ChangeLogVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/vo/ChangeLogVO.java new file mode 100644 index 0000000..10270f4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/domain/vo/ChangeLogVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.module.support.changelog.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.changelog.constant.ChangeLogTypeEnum; + +/** + * 系统更新日志 列表VO + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogVO { + + private Long changeLogId; + + @Schema(description = "版本") + private String updateVersion; + + @SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + private Integer type; + + @Schema(description = "发布人") + private String publishAuthor; + + @Schema(description = "发布日期") + private LocalDate publicDate; + + @Schema(description = "更新内容") + private String content; + + @Schema(description = "跳转链接") + private String link; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/service/ChangeLogService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/service/ChangeLogService.java new file mode 100644 index 0000000..9fd0c84 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/changelog/service/ChangeLogService.java @@ -0,0 +1,97 @@ +package net.lab1024.sa.base.module.support.changelog.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.changelog.dao.ChangeLogDao; +import net.lab1024.sa.base.module.support.changelog.domain.entity.ChangeLogEntity; +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogAddForm; +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogQueryForm; +import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogUpdateForm; +import net.lab1024.sa.base.module.support.changelog.domain.vo.ChangeLogVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 系统更新日志 Service + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Service +public class ChangeLogService { + + @Resource + private ChangeLogDao changeLogDao; + + /** + * 分页查询 + */ + public PageResult queryPage(ChangeLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = changeLogDao.queryPage(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + */ + public synchronized ResponseDTO add(ChangeLogAddForm addForm) { + ChangeLogEntity existVersion = changeLogDao.selectByVersion(addForm.getUpdateVersion()); + if (existVersion != null) { + return ResponseDTO.userErrorParam("此版本已经存在"); + } + + ChangeLogEntity changeLogEntity = SmartBeanUtil.copy(addForm, ChangeLogEntity.class); + changeLogDao.insert(changeLogEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + */ + public synchronized ResponseDTO update(ChangeLogUpdateForm updateForm) { + ChangeLogEntity existVersion = changeLogDao.selectByVersion(updateForm.getUpdateVersion()); + if (existVersion != null && !updateForm.getChangeLogId().equals(existVersion.getChangeLogId())) { + return ResponseDTO.userErrorParam("此版本已经存在"); + } + ChangeLogEntity changeLogEntity = SmartBeanUtil.copy(updateForm, ChangeLogEntity.class); + changeLogDao.updateById(changeLogEntity); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + */ + public synchronized ResponseDTO batchDelete(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return ResponseDTO.ok(); + } + + changeLogDao.deleteBatchIds(idList); + return ResponseDTO.ok(); + } + + /** + * 单个删除 + */ + public synchronized ResponseDTO delete(Long changeLogId) { + if (null == changeLogId) { + return ResponseDTO.ok(); + } + + changeLogDao.deleteById(changeLogId); + return ResponseDTO.ok(); + } + + public ChangeLogVO getById(Long changeLogId) { + return SmartBeanUtil.copy(changeLogDao.selectById(changeLogId), ChangeLogVO.class); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeDeleteEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeDeleteEnum.java new file mode 100644 index 0000000..ac0e007 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeDeleteEnum.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.module.support.codegenerator.constant; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 删除类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum CodeDeleteEnum implements BaseEnum { + + SINGLE("Single", "单个删除"), + BATCH("Batch", "批量删除"), + SINGLE_AND_BATCH("SingleAndBatch", "单个和批量删除"); + + private String value; + + private String desc; + + CodeDeleteEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeFrontComponentEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeFrontComponentEnum.java new file mode 100644 index 0000000..10c8779 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeFrontComponentEnum.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.codegenerator.constant; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 前端组件类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 20:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum CodeFrontComponentEnum implements BaseEnum { + + INPUT("Input", "输入框"), + + INPUT_NUMBER("InputNumber", "数字输入框"), + + TEXTAREA("Textarea", " 文本"), + + BOOLEAN_SELECT("BooleanSelect", "布尔下拉框"), + + ENUM_SELECT("SmartEnumSelect", "枚举下拉"), + + DICT_SELECT("DictSelect", "字典下拉"), + + DATE("Date", "日期选择"), + + DATE_TIME("DateTime", "时间选择"), + + FILE_UPLOAD("FileUpload", "文件上传"); + + private String value; + + private String desc; + + CodeFrontComponentEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorConstant.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorConstant.java new file mode 100644 index 0000000..c0f436d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorConstant.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.codegenerator.constant; + +/** + * 常量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class CodeGeneratorConstant { + + /** + * 默认逻辑删除字段名称 + */ + public static String DELETED_FLAG = "deleted_flag"; + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java new file mode 100644 index 0000000..536f3b8 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.module.support.codegenerator.constant; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 页面类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 19:11:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum CodeGeneratorPageTypeEnum implements BaseEnum { + + MODAL("modal", "弹窗"), + DRAWER("drawer", "抽屉"), + PAGE("page", "新页面"); + + private String value; + + private String desc; + + CodeGeneratorPageTypeEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java new file mode 100644 index 0000000..2e6cbd7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.module.support.codegenerator.constant; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 查询条件类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 20:23:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum CodeQueryFieldQueryTypeEnum implements BaseEnum { + + LIKE("Like", "模糊查询"), + EQUAL("Equal", "等于"), + DATE_RANGE("DateRange", "日期范围"), + DATE("Date", "指定日期"), + ENUM("Enum", "枚举"), + + DICT("Dict", "字典"), + ; + + private String value; + + private String desc; + + CodeQueryFieldQueryTypeEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/controller/CodeGeneratorController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/controller/CodeGeneratorController.java new file mode 100644 index 0000000..c72f690 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/controller/CodeGeneratorController.java @@ -0,0 +1,97 @@ +package net.lab1024.sa.base.module.support.codegenerator.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartResponseUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorPreviewForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.TableQueryForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableColumnVO; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableConfigVO; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableVO; +import net.lab1024.sa.base.module.support.codegenerator.service.CodeGeneratorService; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; + +/** + * 代码生成 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 20:23:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.CODE_GENERATOR) +@Controller +public class CodeGeneratorController extends SupportBaseController { + + @Resource + private CodeGeneratorService codeGeneratorService; + + // ------------------- 查询 ------------------- + + @Operation(summary = "获取表的列 @author 卓大") + @GetMapping("/codeGenerator/table/getTableColumns/{table}") + @ResponseBody + public ResponseDTO> getTableColumns(@PathVariable String table) { + return ResponseDTO.ok(codeGeneratorService.getTableColumns(table)); + } + + @Operation(summary = "查询数据库的表 @author 卓大") + @PostMapping("/codeGenerator/table/queryTableList") + @ResponseBody + public ResponseDTO> queryTableList(@RequestBody @Valid TableQueryForm tableQueryForm) { + return ResponseDTO.ok(codeGeneratorService.queryTableList(tableQueryForm)); + } + + // ------------------- 配置 ------------------- + + @Operation(summary = "获取表的配置信息 @author 卓大") + @GetMapping("/codeGenerator/table/getConfig/{table}") + @ResponseBody + public ResponseDTO getTableConfig(@PathVariable String table) { + return ResponseDTO.ok(codeGeneratorService.getTableConfig(table)); + } + + @Operation(summary = "更新配置信息 @author 卓大") + @PostMapping("/codeGenerator/table/updateConfig") + @ResponseBody + public ResponseDTO updateConfig(@RequestBody @Valid CodeGeneratorConfigForm form) { + return codeGeneratorService.updateConfig(form); + } + + // ------------------- 生成 ------------------- + + @Operation(summary = "代码预览 @author 卓大") + @PostMapping("/codeGenerator/code/preview") + @ResponseBody + public ResponseDTO preview(@RequestBody @Valid CodeGeneratorPreviewForm form) { + return codeGeneratorService.preview(form); + } + + @Operation(summary = "代码下载 @author 卓大") + @GetMapping(value = "/codeGenerator/code/download/{tableName}", produces = "application/octet-stream") + public void download(@PathVariable String tableName, HttpServletResponse response) throws IOException { + + ResponseDTO download = codeGeneratorService.download(tableName); + + if (download.getOk()) { + SmartResponseUtil.setDownloadFileHeader(response, tableName + "_code.zip", (long) download.getData().length); + response.getOutputStream().write(download.getData()); + } else { + SmartResponseUtil.write(response, download); + } + } + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorConfigDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorConfigDao.java new file mode 100644 index 0000000..b9763c6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorConfigDao.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.base.module.support.codegenerator.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.codegenerator.domain.entity.CodeGeneratorConfigEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 表的 代码生成配置 Dao + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-09-23 20:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface CodeGeneratorConfigDao extends BaseMapper { + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorDao.java new file mode 100644 index 0000000..ab609ad --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorDao.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.base.module.support.codegenerator.dao; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.TableQueryForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableColumnVO; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @Author 1024创新实验室: 罗伊 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface CodeGeneratorDao { + + /** + * 分页查询表 + */ + List queryTableList(Page page, @Param("queryForm") TableQueryForm queryForm); + + /** + * 查询表是否存在 + * + * @param tableName + * @return + */ + long countByTableName(@Param("tableName") String tableName); + + + /** + * 查询表列信息 + * + * @param tableName + * @return + */ + List selectTableColumn(@Param("tableName") String tableName); +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java new file mode 100644 index 0000000..b686d54 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 代码生成-配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_code_generator_config") +public class CodeGeneratorConfigEntity { + + /** + * 表名 + */ + @TableId(type = IdType.NONE) + private String tableName; + + /** + * 基础命名信息 + */ + private String basic; + + /** + * 字段列表 + */ + private String fields; + + /** + * 增加、修改 信息 + */ + private String insertAndUpdate; + + /** + * 删除 信息 + */ + private String deleteInfo; + + /** + * 查询字段 + */ + private String queryFields; + + /** + * 列表字段 + */ + private String tableFields; + + /** + * 详情 + */ + private String detail; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java new file mode 100644 index 0000000..4e3c039 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java @@ -0,0 +1,63 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.*; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 代码生成 配置信息表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 20:23:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CodeGeneratorConfigForm { + + @NotBlank(message = "表名 不能为空") + @Schema(description = "表名") + private String tableName; + + @Valid + @NotNull(message = "基础信息不能为空") + @Schema(description = "基础信息") + private CodeBasic basic; + + @Valid + @NotNull(message = "字段信息不能为空") + @Schema(description = "字段信息") + private List fields; + + @Valid + @NotNull(message = "增加、修改 信息 不能为空") + @Schema(description = "增加、修改 信息") + private CodeInsertAndUpdate insertAndUpdate; + + @Valid + @NotNull(message = "删除 信息 不能为空") + @Schema(description = "删除 信息") + private CodeDelete deleteInfo; + + @Valid + @Schema(description = "查询字段") + private List queryFields; + + @Valid + @Schema(description = "列表字段") + private List tableFields; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java new file mode 100644 index 0000000..7aeb309 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 代码生成 预览 表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/6/23 23:20:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class CodeGeneratorPreviewForm { + + @NotBlank(message = "模板文件 不能为空") + @Schema(description = "模板文件") + private String templateFile; + + @NotBlank(message = "表名 不能为空") + @Schema(description = "表名") + private String tableName; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/TableQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/TableQueryForm.java new file mode 100644 index 0000000..bde89a8 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/form/TableQueryForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + + +/** + * 查询表数据 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class TableQueryForm extends PageParam { + + @Schema(description = "表名关键字") + private String tableNameKeywords; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeBasic.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeBasic.java new file mode 100644 index 0000000..ca5d3de --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeBasic.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * 代码生成 基础数据 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeBasic { + + @Schema(description = "业务名称") + @NotBlank(message = "1.基础命名 基础命名 不能为空") + private String moduleName; + + @Schema(description = "java包名") + @NotBlank(message = "1.基础命名 java包名 不能为空") + private String javaPackageName; + + @Schema(description = "注释") + @NotBlank(message = "1.基础命名 注释 不能为空") + private String description; + + @Schema(description = "前端作者") + @NotBlank(message = "1.基础命名 前端作者 不能为空") + private String frontAuthor; + + @Schema(description = "前端时间") + @NotNull(message = "1.基础命名 前端时间 不能为空") + private LocalDateTime frontDate; + + @Schema(description = "后端作者") + @NotBlank(message = "1.基础命名 后端作者 不能为空") + private String backendAuthor; + + @Schema(description = "后端时间") + @NotNull(message = "1.基础命名 后端时间 不能为空") + private LocalDateTime backendDate; + + @Schema(description = "版权信息") + @NotNull(message = "1.基础命名 版权信息 不能为空") + private String copyright; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeDelete.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeDelete.java new file mode 100644 index 0000000..ffc0f5b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeDelete.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeDeleteEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 删除 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeDelete { + + @Schema(description = "是否支持删除 ") + @NotNull(message = "4.删除 是否支持删除 不能为空") + private Boolean isSupportDelete; + + @Schema(description = "是否为物理删除") + @NotNull(message = "4.删除 是否为物理删除 不能为空") + private Boolean isPhysicallyDeleted; + + @Schema(description = "删除类型") + @NotBlank(message = "4.删除 删除类型 不能为空") + @SchemaEnum(CodeDeleteEnum.class) + @CheckEnum(value = CodeDeleteEnum.class, message = "删除 删除类型 枚举值错误") + private String deleteEnum; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeField.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeField.java new file mode 100644 index 0000000..92b184c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeField.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 基础字段 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeField { + + @Schema(description = "列") + @NotBlank(message = " 2.字段列表 列名 不能为空") + private String columnName; + + @Schema(description = "列备注") + private String columnComment; + + @Schema(description = "字段名词") + @NotBlank(message = "2.字段列表 字段名词 不能为空") + private String label; + + @Schema(description = "字段命名") + @NotBlank(message = "2.字段列表 字段命名 不能为空") + private String fieldName; + + @Schema(description = "java类型") + @NotBlank(message = "2.字段列表 java类型 不能为空") + private String javaType; + + @Schema(description = "js类型") + @NotBlank(message = "2.字段列表 js类型 不能为空") + private String jsType; + + @Schema(description = "字典key") + private String dict; + + @Schema(description = "枚举名称") + private String enumName; + + @Schema(description = "主键") + @NotNull(message = "2.字段列表 主键 不能为空") + private Boolean primaryKeyFlag; + + @Schema(description = "自增") + @NotNull(message = "2.字段列表 自增 不能为空") + private Boolean autoIncreaseFlag; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java new file mode 100644 index 0000000..265a23c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeGeneratorPageTypeEnum; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 代码生成 增加、修改 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeInsertAndUpdate { + + @NotNull(message = "3.增加、修改 是否支持增加、修改 不能为空") + private Boolean isSupportInsertAndUpdate; + + @SchemaEnum(CodeGeneratorPageTypeEnum.class) + @CheckEnum(value = CodeGeneratorPageTypeEnum.class, message = "3.增加、修改 增加、修改 页面类型 枚举值错误") + private String pageType; + + @Schema(description = "宽度") + private String width; + + @NotNull(message = "3.增加、修改 每行字段数量 不能为空") + @Schema(description = "每行字段数量") + private Integer countPerLine; + + @Schema(description = "字段列表") + private List fieldList; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java new file mode 100644 index 0000000..5e83fd5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeGeneratorPageTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 增加、修改的字段 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeInsertAndUpdateField { + + @NotBlank(message = "3.增加、修改 列名 不能为空") + @Schema(description = "列名") + private String columnName; + + @NotNull(message = "3.增加、修改 必须 不能为空") + @Schema(description = "必须") + private Boolean requiredFlag; + + @NotNull(message = "3.增加、修改 插入标识 不能为空") + @Schema(description = "插入标识") + private Boolean insertFlag; + + @NotNull(message = "3.增加、修改 更新标识 不能为空") + @Schema(description = "更新标识") + private Boolean updateFlag; + + @SchemaEnum(value = CodeFrontComponentEnum.class) + @CheckEnum(value = CodeFrontComponentEnum.class, message = "3.增加、修改 组件类型 枚举值错误", required = true) + private String frontComponent; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeQueryField.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeQueryField.java new file mode 100644 index 0000000..b4fdb8d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeQueryField.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 代码生成 查询条件 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeQueryField { + + @NotBlank(message = "5、查询条件 条件名称 不能为空") + @Schema(description = "条件名称") + private String label; + + @NotBlank(message = "5、查询条件 字段名 不能为空") + @Schema(description = "字段名") + private String fieldName; + + @SchemaEnum(CodeQueryFieldQueryTypeEnum.class) + @CheckEnum(value = CodeQueryFieldQueryTypeEnum.class, message = "5、查询条件 查询条件 查询类型 枚举值错误") + private String queryTypeEnum; + + @NotEmpty(message = "5、查询条件 列 不能为空") + @Schema(description = "列") + private List columnNameList; + + @NotBlank(message = "5、查询条件 宽度 不能为空") + @Schema(description = "宽度") + private String width; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeTableField.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeTableField.java new file mode 100644 index 0000000..b075402 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeTableField.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.module.support.codegenerator.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 列表表格 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class CodeTableField { + + @NotBlank(message = "6、列表 列名 不能为空") + @Schema(description = "列名") + private String columnName; + + @NotBlank(message = "6、列表 字段名词 不能为空") + @Schema(description = "字段名词") + private String label; + + @NotBlank(message = "6、列表 字段命名 不能为空") + @Schema(description = "字段命名") + private String fieldName; + + @NotNull(message = "6、列表 列表显示 不能为空") + @Schema(description = "列表显示") + private Boolean showFlag; + + @Schema(description = "宽度") + private Integer width; + + @NotNull(message = "6、列表 自动省略标识 不能为空") + @Schema(description = "自动省略标识") + private Boolean ellipsisFlag; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableColumnVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableColumnVO.java new file mode 100644 index 0000000..0fa76e5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableColumnVO.java @@ -0,0 +1,48 @@ + +package net.lab1024.sa.base.module.support.codegenerator.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 列 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/21 21:07:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class TableColumnVO { + + @Schema(description = "列名") + private String columnName; + + @Schema(description = "列描述") + private String columnComment; + + @Schema(description = "数据类型varchar") + private String dataType; + + @Schema(description = "是否为空") + private Boolean nullableFlag; + + @Schema(description = "是否为主键") + private Boolean primaryKeyFlag; + + @Schema(description = "是否递增") + private Boolean autoIncreaseFlag; + + // --------------- 临时字段 ------------------- + + @Schema(hidden = true) + private String columnKey; + + @Schema(hidden = true) + private String extra; + + @Schema(hidden = true) + private String isNullable; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableConfigVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableConfigVO.java new file mode 100644 index 0000000..2dfe0e2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableConfigVO.java @@ -0,0 +1,40 @@ + +package net.lab1024.sa.base.module.support.codegenerator.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.*; + +import java.util.List; + +/** + * 表的配置信息 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/21 21:07:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class TableConfigVO { + + @Schema(description = "基础命名信息") + private CodeBasic basic; + + @Schema(description = "字段列") + private List fields; + + @Schema(description = "增加、修改 信息") + private CodeInsertAndUpdate insertAndUpdate; + + @Schema(description = "删除 信息") + private CodeDelete deleteInfo; + + @Schema(description = "查询字段") + private List queryFields; + + @Schema(description = "列表字段") + private List tableFields; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableVO.java new file mode 100644 index 0000000..3c02730 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableVO.java @@ -0,0 +1,31 @@ + +package net.lab1024.sa.base.module.support.codegenerator.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 表信息 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/21 18:07:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Data +public class TableVO { + + @Schema(description = "表名") + private String tableName; + + @Schema(description = "表备注") + private String tableComment; + + @Schema(description = "配置时间") + private LocalDateTime configTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorService.java new file mode 100644 index 0000000..5dd85e1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorService.java @@ -0,0 +1,241 @@ +package net.lab1024.sa.base.module.support.codegenerator.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeGeneratorConstant; +import net.lab1024.sa.base.module.support.codegenerator.dao.CodeGeneratorConfigDao; +import net.lab1024.sa.base.module.support.codegenerator.dao.CodeGeneratorDao; +import net.lab1024.sa.base.module.support.codegenerator.domain.entity.CodeGeneratorConfigEntity; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorPreviewForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.TableQueryForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.*; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableColumnVO; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableConfigVO; +import net.lab1024.sa.base.module.support.codegenerator.domain.vo.TableVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Optional; + +/** + * 代码生成器 Service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class CodeGeneratorService { + + private static final String COLUMN_NO_NULLABLE_IDENTIFY = "NO"; + + private static final String COLUMN_PRIMARY_KEY = "PRI"; + + private static final String COLUMN_AUTO_INCREASE = "auto_increment"; + + @Resource + private CodeGeneratorDao codeGeneratorDao; + + @Resource + private CodeGeneratorConfigDao codeGeneratorConfigDao; + + @Resource + private CodeGeneratorTemplateService codeGeneratorTemplateService; + + + /** + * 列信息 + * + * @param tableName + * @return + */ + public List getTableColumns(String tableName) { + List tableColumns = codeGeneratorDao.selectTableColumn(tableName); + for (TableColumnVO tableColumn : tableColumns) { + tableColumn.setNullableFlag(!COLUMN_NO_NULLABLE_IDENTIFY.equalsIgnoreCase(tableColumn.getIsNullable())); + tableColumn.setPrimaryKeyFlag(COLUMN_PRIMARY_KEY.equalsIgnoreCase(tableColumn.getColumnKey())); + tableColumn.setAutoIncreaseFlag(SmartStringUtil.isNotEmpty(tableColumn.getExtra()) && COLUMN_AUTO_INCREASE.equalsIgnoreCase(tableColumn.getExtra())); + } + return tableColumns; + } + + + /** + * 查询数据库表数据 + * + * @param tableQueryForm + * @return + */ + public PageResult queryTableList(TableQueryForm tableQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(tableQueryForm); + List tableVOList = codeGeneratorDao.queryTableList(page, tableQueryForm); + return SmartPageUtil.convert2PageResult(page, tableVOList); + } + + /** + * 获取 表的 配置信息 + * + * @param table + * @return + */ + public TableConfigVO getTableConfig(String table) { + + TableConfigVO config = new TableConfigVO(); + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(table); + if (codeGeneratorConfigEntity == null) { + return config; + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getBasic())) { + CodeBasic basic = JSON.parseObject(codeGeneratorConfigEntity.getBasic(), CodeBasic.class); + config.setBasic(basic); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getFields())) { + List fields = JSONArray.parseArray(codeGeneratorConfigEntity.getFields(), CodeField.class); + config.setFields(fields); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getInsertAndUpdate())) { + CodeInsertAndUpdate insertAndUpdate = JSON.parseObject(codeGeneratorConfigEntity.getInsertAndUpdate(), CodeInsertAndUpdate.class); + config.setInsertAndUpdate(insertAndUpdate); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getDeleteInfo())) { + CodeDelete deleteInfo = JSON.parseObject(codeGeneratorConfigEntity.getDeleteInfo(), CodeDelete.class); + config.setDeleteInfo(deleteInfo); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getQueryFields())) { + List queryFields = JSONArray.parseArray(codeGeneratorConfigEntity.getQueryFields(), CodeQueryField.class); + config.setQueryFields(queryFields); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getTableFields())) { + List tableFields = JSONArray.parseArray(codeGeneratorConfigEntity.getTableFields(), CodeTableField.class); + config.setTableFields(tableFields); + } + + return config; + } + + /** + * 更新配置 + * + * @param form + * @return + */ + public synchronized ResponseDTO updateConfig(CodeGeneratorConfigForm form) { + long existCount = codeGeneratorDao.countByTableName(form.getTableName()); + if (existCount == 0) { + return ResponseDTO.userErrorParam("表不存在,请联系后端查看下数据库"); + } + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(form.getTableName()); + boolean updateFlag = true; + if (codeGeneratorConfigEntity == null) { + codeGeneratorConfigEntity = new CodeGeneratorConfigEntity(); + updateFlag = false; + } + + // 校验假删,必须有 deleted_flag 字段 + List tableColumns = getTableColumns(form.getTableName()); + if (null != form.getDeleteInfo() && form.getDeleteInfo().getIsSupportDelete() && !form.getDeleteInfo().getIsPhysicallyDeleted()) { + Optional any = tableColumns.stream().filter(e -> e.getColumnName().equals(CodeGeneratorConstant.DELETED_FLAG)).findAny(); + if (!any.isPresent()) { + return ResponseDTO.userErrorParam("表结构中没有假删字段:" + CodeGeneratorConstant.DELETED_FLAG + ",请仔细排查"); + } + } + + // 校验表必须有主键 + if (tableColumns.stream().noneMatch(e -> COLUMN_PRIMARY_KEY.equalsIgnoreCase(e.getColumnKey()))) { + return ResponseDTO.userErrorParam("表必须有主键,请联系后端查看下数据库表结构"); + } + + codeGeneratorConfigEntity.setTableName(form.getTableName()); + codeGeneratorConfigEntity.setBasic(JSON.toJSONString(form.getBasic())); + codeGeneratorConfigEntity.setFields(JSONArray.toJSONString(form.getFields())); + codeGeneratorConfigEntity.setInsertAndUpdate(JSON.toJSONString(form.getInsertAndUpdate())); + codeGeneratorConfigEntity.setDeleteInfo(JSON.toJSONString(form.getDeleteInfo())); + codeGeneratorConfigEntity.setQueryFields(JSONArray.toJSONString(form.getQueryFields())); + codeGeneratorConfigEntity.setTableFields(JSONArray.toJSONString(form.getTableFields())); + + if (updateFlag) { + codeGeneratorConfigDao.updateById(codeGeneratorConfigEntity); + } else { + codeGeneratorConfigDao.insert(codeGeneratorConfigEntity); + } + return ResponseDTO.ok(); + } + + /** + * 预览 + * + * @param form + * @return + */ + public ResponseDTO preview(CodeGeneratorPreviewForm form) { + long existCount = codeGeneratorDao.countByTableName(form.getTableName()); + if (existCount == 0) { + return ResponseDTO.userErrorParam("表不存在,请联系后端查看下数据库"); + } + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(form.getTableName()); + if (codeGeneratorConfigEntity == null) { + return ResponseDTO.userErrorParam("配置信息不存在,请先进行配置"); + } + + List columns = getTableColumns(form.getTableName()); + if (CollectionUtils.isEmpty(columns)) { + return ResponseDTO.userErrorParam("表没有列信息无法生成"); + } + + String result = codeGeneratorTemplateService.generate(form.getTableName(), form.getTemplateFile(), codeGeneratorConfigEntity); + return ResponseDTO.ok(result); + + } + + /** + * 下载代码 + * + * @param tableName + * @return + */ + public ResponseDTO download(String tableName) { + if (SmartStringUtil.isBlank(tableName)) { + return ResponseDTO.userErrorParam("表名不能为空"); + } + + long existCount = codeGeneratorDao.countByTableName(tableName); + if (existCount == 0) { + return ResponseDTO.userErrorParam("表不存在,请联系后端查看下数据库"); + } + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(tableName); + if (codeGeneratorConfigEntity == null) { + return ResponseDTO.userErrorParam("配置信息不存在,请先进行配置"); + } + + List columns = getTableColumns(tableName); + if (CollectionUtils.isEmpty(columns)) { + return ResponseDTO.userErrorParam("表没有列信息无法生成"); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + codeGeneratorTemplateService.zipGeneratedFiles(out, tableName, codeGeneratorConfigEntity); + return ResponseDTO.ok(out.toByteArray()); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorTemplateService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorTemplateService.java new file mode 100644 index 0000000..dddc985 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorTemplateService.java @@ -0,0 +1,244 @@ +package net.lab1024.sa.base.module.support.codegenerator.service; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ZipUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.google.common.base.CaseFormat; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.domain.entity.CodeGeneratorConfigEntity; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.*; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.*; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain.*; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.front.ApiVariableService; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.front.ConstVariableService; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.front.FormVariableService; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.front.ListVariableService; +import net.lab1024.sa.base.module.support.codegenerator.util.CodeGeneratorTool; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.velocity.Template; +import org.apache.velocity.app.Velocity; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.tools.ToolContext; +import org.apache.velocity.tools.ToolManager; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.io.OutputStream; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 代码生成器 模板 Service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Service +@Slf4j +public class CodeGeneratorTemplateService { + + + private Map map = new HashMap<>(); + + @PostConstruct + public void init() { + // 后端 + map.put("java/domain/entity/Entity.java", new EntityVariableService()); + map.put("java/domain/form/AddForm.java", new AddFormVariableService()); + map.put("java/domain/form/UpdateForm.java", new UpdateFormVariableService()); + map.put("java/domain/form/QueryForm.java", new QueryFormVariableService()); + map.put("java/domain/vo/VO.java", new VOVariableService()); + map.put("java/controller/Controller.java", new ControllerVariableService()); + map.put("java/service/Service.java", new ServiceVariableService()); + map.put("java/manager/Manager.java", new ManagerVariableService()); + map.put("java/dao/Dao.java", new DaoVariableService()); + map.put("java/mapper/Mapper.xml", new MapperVariableService()); + // 菜单 SQL + map.put("java/sql/Menu.sql", new MenuVariableService()); + // 前端 + map.put("js/api.js", new ApiVariableService()); + map.put("js/const.js", new ConstVariableService()); + map.put("js/list.vue", new ListVariableService()); + map.put("js/form.vue", new FormVariableService()); + // ts前端 + map.put("ts/api.ts", new ApiVariableService()); + map.put("ts/const.ts", new ConstVariableService()); + map.put("ts/list.vue", new ListVariableService()); + map.put("ts/form.vue", new FormVariableService()); + } + + public void zipGeneratedFiles(OutputStream outputStream, String tableName, CodeGeneratorConfigEntity codeGeneratorConfigEntity) { + String uuid = IdUtil.fastSimpleUUID(); + File dir = new File(uuid); + + // 1、生产文件 + CodeBasic basic = JSON.parseObject(codeGeneratorConfigEntity.getBasic(), CodeBasic.class); + String moduleName = basic.getModuleName(); + + for (Map.Entry entry : map.entrySet()) { + try { + String templateFile = entry.getKey(); + String upperCamel = new CodeGeneratorTool().lowerCamel2UpperCamel(moduleName); + String lowerHyphen = new CodeGeneratorTool().lowerCamel2LowerHyphen(moduleName); + String[] templateSplit = templateFile.split("/"); + String fileName = templateFile.startsWith("java") ? upperCamel + templateSplit[templateSplit.length - 1] : lowerHyphen + "-" + templateSplit[templateSplit.length - 1]; + String fullPathFileName = templateFile.replaceAll(templateSplit[templateSplit.length - 1], fileName); + fullPathFileName = fullPathFileName.replaceAll("java/", "java/" + basic.getModuleName().toLowerCase() + "/"); + fullPathFileName = fullPathFileName.replaceAll("js/", "js/" + lowerHyphen + "/"); + + String fileContent = generate(tableName, templateFile, codeGeneratorConfigEntity); + File file = new File(uuid + "/" + fullPathFileName); + file.getParentFile().mkdirs(); + FileUtil.appendUtf8String(fileContent, file); + } catch (IORuntimeException e) { + log.error(e.getMessage(), e); + } + } + + // 2、后端的枚举文件 + List fields = JSONArray.parseArray(codeGeneratorConfigEntity.getFields(), CodeField.class); + if (CollectionUtils.isNotEmpty(fields)) { + List enumFiledList = fields.stream().filter(e -> SmartStringUtil.isNotBlank(e.getEnumName())).collect(Collectors.toList()); + for (CodeField codeField : enumFiledList) { + Map variablesMap = new HashMap<>(); + + String enumName = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, codeField.getEnumName()); + if (!enumName.endsWith("Enum")) { + enumName = enumName + "Enum"; + } + variablesMap.put("enumName", enumName); + variablesMap.put("enumDesc", codeField.getColumnComment()); + variablesMap.put("enumJavaType", codeField.getJavaType()); + variablesMap.put("basic", basic); + variablesMap.put("packageName", basic.getJavaPackageName() + ".constant"); + + String fileContent = render("code-generator-template/java/constant/enum.java.vm", variablesMap); + File file = new File(uuid + "/java/" + basic.getModuleName().toLowerCase() + "/constant/" + enumName + ".java"); + file.getParentFile().mkdirs(); + FileUtil.appendUtf8String(fileContent, file); + } + } + + + ZipUtil.zip(outputStream, StandardCharsets.UTF_8, false, null, dir); + + FileUtil.del(dir); + + } + + + public String generate(String tableName, String file, CodeGeneratorConfigEntity codeGeneratorConfigEntity) { + + // -------------------- 1 校验不支持的代码生成,比如增加、删除等 -------------------- + + String finalFile = file; + Optional optional = map.keySet().stream().filter(e -> e.contains(finalFile)).findFirst(); + if (!optional.isPresent()) { + return "不存在此模板!"; + } + + file = optional.get(); + CodeGenerateBaseVariableService codeGenerateBaseVariableService = map.get(file); + if (codeGenerateBaseVariableService == null) { + return "代码生成Service不存在,请检查相关代码!"; + } + + CodeBasic basic = JSON.parseObject(codeGeneratorConfigEntity.getBasic(), CodeBasic.class); + List fields = JSONArray.parseArray(codeGeneratorConfigEntity.getFields(), CodeField.class); + CodeInsertAndUpdate insertAndUpdate = JSON.parseObject(codeGeneratorConfigEntity.getInsertAndUpdate(), CodeInsertAndUpdate.class); + CodeDelete deleteInfo = JSON.parseObject(codeGeneratorConfigEntity.getDeleteInfo(), CodeDelete.class); + List queryFields = JSONArray.parseArray(codeGeneratorConfigEntity.getQueryFields(), CodeQueryField.class); + List tableFields = JSONArray.parseArray(codeGeneratorConfigEntity.getTableFields(), CodeTableField.class); + tableFields.forEach(e -> e.setWidth(e.getWidth() == null ? 0 : e.getWidth())); + + CodeGeneratorConfigForm form = CodeGeneratorConfigForm.builder().basic(basic).fields(fields).insertAndUpdate(insertAndUpdate).deleteInfo(deleteInfo).queryFields(queryFields).tableFields(tableFields).deleteInfo(deleteInfo).build(); + form.setTableName(tableName); + if (!codeGenerateBaseVariableService.isSupport(form)) { + return "业务不需要此功能,故没有生成代码;"; + } + + // -------------------- 2 通用模板的变量 -------------------- + Map variablesMap = new HashMap<>(); + + + Map basicMap = BeanUtil.beanToMap(basic); + basicMap.put("frontDate", DateUtil.formatLocalDateTime(basic.getFrontDate())); + basicMap.put("backendDate", DateUtil.formatLocalDateTime(basic.getBackendDate())); + + variablesMap.put("basic", basicMap); + variablesMap.put("fields", fields); + variablesMap.put("insertAndUpdate", insertAndUpdate); + variablesMap.put("deleteInfo", deleteInfo); + variablesMap.put("queryFields", queryFields); + variablesMap.put("tableFields", tableFields); + variablesMap.put("tableName", tableName); + + //名词的大写开头和小写开头 + HashMap names = new HashMap<>(); + names.put("lowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, basic.getModuleName())); + names.put("upperCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_CAMEL, basic.getModuleName())); + names.put("lowerHyphenCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, basic.getModuleName())); + variablesMap.put("name", names); + + //主键字段名称和java类型 + CodeField primaryKeycodeField = fields.stream().filter(e -> e.getPrimaryKeyFlag()).findFirst().get(); + if (primaryKeycodeField != null) { + variablesMap.put("primaryKeyJavaType", primaryKeycodeField.getJavaType()); + variablesMap.put("primaryKeyFieldName", primaryKeycodeField.getFieldName()); + variablesMap.put("primaryKeyColumnName", primaryKeycodeField.getColumnName()); + } + + // -------------------- 3、针对此 模板 的特殊变量 -------------------- + + Map specialVariables = codeGenerateBaseVariableService.getInjectVariablesMap(form); + variablesMap.putAll(specialVariables); + + // -------------------- 4、模板 生成代码 -------------------- + + return render("code-generator-template/" + file + ".vm", variablesMap); + } + + /** + * 渲染 + * + * @param templateFile + * @param variablesMap + * @return + */ + private String render(String templateFile, Map variablesMap) { + VelocityEngine engine = new VelocityEngine(); + engine.setProperty(Velocity.FILE_RESOURCE_LOADER_CACHE, true); + engine.setProperty(Velocity.INPUT_ENCODING, "UTF-8"); + engine.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + engine.init(); + Template template = engine.getTemplate(templateFile); + + //加载tools.xml配置文件 + ToolManager toolManager = new ToolManager(); + toolManager.configure("code-generator-template/tools.xml"); + + //注入变量 + ToolContext context = toolManager.createContext(); + context.putAll(variablesMap); + + StringWriter sw = new StringWriter(); + template.merge(context, sw); + return sw.toString(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java new file mode 100644 index 0000000..b2e026e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java @@ -0,0 +1,151 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable; + +import com.google.common.base.CaseFormat; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdate; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public abstract class CodeGenerateBaseVariableService { + + public abstract Map getInjectVariablesMap(CodeGeneratorConfigForm form); + + /** + * 是否支持 : + * 1、增加、修改 + * 2、删除 + * + * @param form + * @return + */ + public abstract boolean isSupport(CodeGeneratorConfigForm form); + + /** + * 获取所有javabean的 import 包名 + * + * @param form + * @return + */ + public List getJavaBeanImportClass(CodeGeneratorConfigForm form) { + String upperCamelName = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_CAMEL, form.getBasic().getModuleName()); + ArrayList list = new ArrayList<>(); + + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.entity." + upperCamelName + "Entity;"); + + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.form." + upperCamelName + "AddForm;"); + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.form." + upperCamelName + "UpdateForm;"); + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.form." + upperCamelName + "QueryForm;"); + + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.vo." + upperCamelName + "VO;"); + return list; + } + + + /** + * 根据列名查找 CodeField + */ + public CodeField getCodeFieldByColumnName(String columnName, CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (CollectionUtils.isEmpty(fields)) { + return null; + } + + return fields.stream().filter(e -> SmartStringUtil.equals(columnName, e.getColumnName())).findFirst().orElse(null); + } + + + /** + * 是否为文件上传字段 + */ + protected boolean isFile(String columnName, CodeGeneratorConfigForm form) { + CodeInsertAndUpdate insertAndUpdate = form.getInsertAndUpdate(); + if (insertAndUpdate == null) { + return false; + } + + List fieldList = insertAndUpdate.getFieldList(); + if (CollectionUtils.isEmpty(fieldList)) { + return false; + } + + Optional first = fieldList.stream().filter(e -> columnName.equals(e.getColumnName())).findFirst(); + if (!first.isPresent()) { + return false; + } + + CodeInsertAndUpdateField field = first.get(); + return CodeFrontComponentEnum.FILE_UPLOAD.equalsValue(field.getFrontComponent()); + } + + /** + * 是否为 字典 + */ + protected boolean isDict(String columnName, CodeGeneratorConfigForm form) { + CodeField codeField = getCodeField(columnName, form); + return codeField != null && codeField.getDict() != null; + } + + /** + * 是否为 枚举 + */ + protected boolean isEnum(String columnName, CodeGeneratorConfigForm form) { + CodeField codeField = getCodeField(columnName, form); + return codeField != null && codeField.getEnumName() != null; + } + + private CodeField getCodeField(String columnName, CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (CollectionUtils.isEmpty(fields)) { + return null; + } + + return fields.stream().filter(e -> columnName.equals(e.getColumnName())).findFirst().orElse(null); + } + + /** + * 获取字段集合 + * + * @param form + * @return + */ + protected Map getFieldMap(CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (fields == null) { + return new HashMap<>(); + } + + return fields.stream().collect(Collectors.toMap(CodeField::getColumnName, Function.identity())); + } + + /** + * 获取java类型 + * + * @return + */ + protected String getJavaPackageName(String javaType) { + if ("BigDecimal".equals(javaType)) { + return "import java.math.BigDecimal;"; + } else if ("LocalDate".equals(javaType)) { + return "import java.time.LocalDate;"; + } else if ("LocalDateTime".equals(javaType)) { + return "import java.time.LocalDateTime;"; + } else { + return null; + } + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ControllerVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ControllerVariableService.java new file mode 100644 index 0000000..167bd16 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ControllerVariableService.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend; + +import com.google.common.base.CaseFormat; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeDeleteEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class ControllerVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".controller"); + + List packageList = getPackageList(updateFieldList, form); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageSet = new HashSet<>(); + + //1、javabean相关的包 + packageSet.addAll(getJavaBeanImportClass(form).stream().filter(e -> !e.contains("Entity;")).collect(Collectors.toList())); + + //2、其他包 + if (form.getDeleteInfo().getIsSupportDelete()) { + + CodeDeleteEnum codeDeleteEnum = SmartEnumUtil.getEnumByValue(form.getDeleteInfo().getDeleteEnum(), CodeDeleteEnum.class); + if (codeDeleteEnum == CodeDeleteEnum.BATCH || codeDeleteEnum == CodeDeleteEnum.SINGLE_AND_BATCH) { + //2、批量删除的话,要导入ValidateList + packageSet.add("import net.lab1024.sa.base.common.domain.ValidateList;"); + } + + if (codeDeleteEnum == CodeDeleteEnum.SINGLE || codeDeleteEnum == CodeDeleteEnum.SINGLE_AND_BATCH) { + //3、单个删除的话,要导入 @PathVariable + packageSet.add("import org.springframework.web.bind.annotation.PathVariable;"); + packageSet.add("import org.springframework.web.bind.annotation.GetMapping;"); + } + } + + packageSet.add("import " + form.getBasic().getJavaPackageName() + ".service." + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, form.getBasic().getModuleName()) + "Service;"); + + // 排序一下 + ArrayList packageList = new ArrayList<>(packageSet); + Collections.sort(packageList); + return packageList; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/DaoVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/DaoVariableService.java new file mode 100644 index 0000000..b4d313f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/DaoVariableService.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class DaoVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + List packageList = getPackageList(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".dao" ); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageSet = new HashSet<>(); + + //1、javabean相关的包 + packageSet.addAll(getJavaBeanImportClass(form).stream().filter( e-> e.contains("QueryForm;") || e.contains("VO;")|| e.contains("Entity;")).collect(Collectors.toList())); + + //2、util + packageSet.add("import java.util.List;"); + + //3、 排序一下 + ArrayList packageList = new ArrayList<>(packageSet); + Collections.sort(packageList); + return packageList; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ManagerVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ManagerVariableService.java new file mode 100644 index 0000000..c46fdb5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ManagerVariableService.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class ManagerVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + List packageList = getPackageList(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".manager" ); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageList = new HashSet<>(); + + //1、javabean相关的包 + packageList.addAll(getJavaBeanImportClass(form).stream().filter(e -> e.contains("Entity;")).collect(Collectors.toList())); + + //2、dao + packageList.add("import " + form.getBasic().getJavaPackageName() + ".dao."+ form.getBasic().getModuleName() + "Dao;" ); + return new ArrayList<>(packageList); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/MenuVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/MenuVariableService.java new file mode 100644 index 0000000..17ab19f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/MenuVariableService.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.HashMap; +import java.util.Map; + +/** + * 目前暂时没用到 这是一个空实现 + * + * @author zhoumingfa + * @date 2024/8/13 + */ +public class MenuVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + return new HashMap<>(2); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ServiceVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ServiceVariableService.java new file mode 100644 index 0000000..fb5750b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ServiceVariableService.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class ServiceVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + List packageList = getPackageList(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".service" ); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageSet = new HashSet<>(); + + //1、javabean相关的包 + packageSet.addAll(getJavaBeanImportClass(form)); + + //2、dao + packageSet.add("import " + form.getBasic().getJavaPackageName() + ".dao."+ form.getBasic().getModuleName() + "Dao;" ); + + //3、util list + packageSet.add("import java.util.List;"); + + //3、 排序一下 + ArrayList packageList = new ArrayList<>(packageSet); + Collections.sort(packageList); + return packageList; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java new file mode 100644 index 0000000..23612e4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java @@ -0,0 +1,131 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdate; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class AddFormVariableService extends CodeGenerateBaseVariableService { + + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + CodeInsertAndUpdate insertAndUpdate = form.getInsertAndUpdate(); + return insertAndUpdate != null && insertAndUpdate.getIsSupportInsertAndUpdate() != null && insertAndUpdate.getIsSupportInsertAndUpdate(); + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeInsertAndUpdateField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.base.common.swagger.SchemaEnum;"); + packageList.add("import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnumPrefix = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\""; + String checkEnum = checkEnumPrefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + + finalFieldMap.put("apiModelProperty", "@SchemaEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + } else { + String prefix = "@Schema(description = \"" + codeField.getLabel() + "\""; + String apiModelProperty = prefix + (field.getRequiredFlag() ? ", requiredMode = Schema.RequiredMode.REQUIRED)" : ")"); + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.v3.oas.annotations.media.Schema;"); + + if (Boolean.TRUE.equals(field.getRequiredFlag())) { + String notEmptyPrefix = "String".equals(codeField.getJavaType()) ? "@NotBlank" : "@NotNull"; + finalFieldMap.put("notEmpty", "\n " + notEmptyPrefix + "(message = \"" + codeField.getLabel() + " 不能为空\")"); + packageList.add("String".equals(codeField.getJavaType()) ? "import javax.validation.constraints.NotBlank;" + : "import javax.validation.constraints.NotNull;"); + } + } + + //字典 + if (SmartStringUtil.isNotEmpty(codeField.getDict())) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictDataDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer;"); + } + + //文件上传 + if (CodeFrontComponentEnum.FILE_UPLOAD.equalsValue(field.getFrontComponent())) { + finalFieldMap.put("file", "\n @JsonDeserialize(using = FileKeyVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java new file mode 100644 index 0000000..391bffa --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java @@ -0,0 +1,80 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain; + +import com.google.common.collect.Lists; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class EntityVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.entity"); + variablesMap.put("importPackageList", getImportPackageList(form.getFields())); + + + return variablesMap; + } + + + public List getImportPackageList(List fields) { + if (CollectionUtils.isEmpty(fields)) { + return Lists.newArrayList(); + } + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + List result = fields.stream().map(e -> getJavaPackageName(e.getJavaType())).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + + // lombok + result.add("import lombok.Data;"); + + // mybatis plus + result.add("import com.baomidou.mybatisplus.annotation.TableName;"); + + // 自动填充注解 + boolean existCreateAndUpdate = fields.stream().anyMatch(e -> "create_time".equals(e.getColumnName()) || "update_time".equals(e.getColumnName())); + if (existCreateAndUpdate) { + result.add("import com.baomidou.mybatisplus.annotation.FieldFill;"); + result.add("import com.baomidou.mybatisplus.annotation.TableField;"); + } + + //主键 + boolean isExistPrimaryKey = fields.stream().anyMatch(e -> e.getPrimaryKeyFlag() != null && e.getPrimaryKeyFlag()); + if (isExistPrimaryKey) { + result.add("import com.baomidou.mybatisplus.annotation.TableId;"); + } + + //自增 + boolean isExistAutoIncrease = fields.stream().anyMatch(e -> e.getAutoIncreaseFlag() != null && e.getAutoIncreaseFlag()); + if (isExistAutoIncrease) { + result.add("import com.baomidou.mybatisplus.annotation.IdType;"); + } + + Collections.sort(result); + return result; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java new file mode 100644 index 0000000..68b77e4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeQueryField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class MapperVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + List> finalQueryFiledList = new ArrayList<>(); + for (CodeQueryField queryField : form.getQueryFields()) { + Map fieldMap = BeanUtil.beanToMap(queryField); + finalQueryFiledList.add(fieldMap); + + //模糊查询 + if (CodeQueryFieldQueryTypeEnum.LIKE.getValue().equals(queryField.getQueryTypeEnum())) { + StringBuilder stringBuilder = new StringBuilder(); + List columnNameList = queryField.getColumnNameList(); + if (columnNameList.size() == 1) { + // AND INSTR(t_notice.title,#{query.keywords}) + stringBuilder.append("AND INSTR(") + .append(form.getTableName()).append(".").append(queryField.getColumnNameList().get(0)) + .append(",#{queryForm.") + .append(queryField.getFieldName()) + .append("})"); + } else { + for (int i = 0; i < columnNameList.size(); i++) { + if (i == 0) { + stringBuilder.append("AND (\n INSTR(") + .append(form.getTableName()).append(".").append(queryField.getColumnNameList().get(i)) + .append(",#{queryForm.") + .append(queryField.getFieldName()) + .append("})"); + } else { + // OR INSTR(t_notice.author,#{query.keywords}) + stringBuilder.append("\n OR INSTR(") + .append(form.getTableName()).append(".").append(queryField.getColumnNameList().get(i)) + .append(",#{queryForm.") + .append(queryField.getFieldName()) + .append("})"); + } + } + stringBuilder.append("\n )"); + } + fieldMap.put("likeStr", stringBuilder.toString()); + } else if (CodeQueryFieldQueryTypeEnum.DICT.equalsValue(queryField.getQueryTypeEnum())) { + String stringBuilder = "AND INSTR(" + + form.getTableName() + "." + queryField.getColumnNameList().get(0) + + ",#{queryForm." + + queryField.getFieldName() + + "})"; + fieldMap.put("likeStr", stringBuilder); + } + else { + fieldMap.put("columnName", queryField.getColumnNameList().get(0)); + } + } + + variablesMap.put("queryFields", finalQueryFiledList); + variablesMap.put("daoClassName", form.getBasic().getJavaPackageName() + ".dao." + form.getBasic().getModuleName() + "Dao"); + return variablesMap; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java new file mode 100644 index 0000000..028275b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java @@ -0,0 +1,129 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeQueryField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class QueryFormVariableService extends CodeGenerateBaseVariableService { + + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(form); + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + return variablesMap; + } + + + public ImmutablePair, List>> getPackageListAndFields(CodeGeneratorConfigForm form) { + + List fields = form.getQueryFields(); + + HashSet packageList = new HashSet<>(); + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeQueryField field : fields) { + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(field)); + + String queryTypeEnumStr = field.getQueryTypeEnum(); + CodeQueryFieldQueryTypeEnum queryTypeEnum = SmartEnumUtil.getEnumByValue(queryTypeEnumStr, CodeQueryFieldQueryTypeEnum.class); + if (queryTypeEnum == null) { + continue; + } + + String apiModelProperty = "@Schema(description = \"" + field.getLabel() + "\")"; + finalFieldMap.put("apiModelProperty", apiModelProperty); + packageList.add("import io.swagger.v3.oas.annotations.media.Schema;"); + + CodeField codeField = null; + + switch (queryTypeEnum) { + case EQUAL: + codeField = getCodeFieldByColumnName(field.getColumnNameList().get(0), form); + if (codeField == null) { + finalFieldMap.put("javaType", "String"); + } else { + finalFieldMap.put("javaType", codeField.getJavaType()); + } + break; + case DATE_RANGE: + case DATE: + packageList.add("import java.time.LocalDate;"); + finalFieldMap.put("javaType", "LocalDate"); + break; + case ENUM: + codeField = getCodeFieldByColumnName(field.getColumnNameList().get(0), form); + if (codeField == null) { + continue; + } + + packageList.add("import net.lab1024.sa.base.common.swagger.SchemaEnum;"); + packageList.add("import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnum = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\")"; + finalFieldMap.put("apiModelProperty", "@SchemaEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + finalFieldMap.put("javaType", codeField.getJavaType()); + break; + case DICT: + codeField = getCodeFieldByColumnName(field.getColumnNameList().get(0), form); + if (SmartStringUtil.isNotEmpty(codeField.getDict())) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictDataDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer;"); + } + finalFieldMap.put("javaType", "String"); + default: + finalFieldMap.put("javaType", "String"); + } + + finalFieldList.add(finalFieldMap); + } + + // lombok + packageList.add("import lombok.Data;"); + packageList.add("import lombok.EqualsAndHashCode;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).sorted().collect(Collectors.toList()); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java new file mode 100644 index 0000000..f8d2637 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java @@ -0,0 +1,146 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdate; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class UpdateFormVariableService extends CodeGenerateBaseVariableService { + + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + CodeInsertAndUpdate insertAndUpdate = form.getInsertAndUpdate(); + return insertAndUpdate != null && insertAndUpdate.getIsSupportInsertAndUpdate() != null && insertAndUpdate.getIsSupportInsertAndUpdate(); + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + Map fieldMap = getFieldMap(form); + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> { + boolean isUpdate = Boolean.TRUE.equals(e.getUpdateFlag()); + CodeField codeField = fieldMap.get(e.getColumnName()); + if (codeField == null) { + return false; + } + + if (Boolean.TRUE.equals(codeField.getPrimaryKeyFlag())) { + e.setRequiredFlag(true); + } + + return isUpdate || Boolean.TRUE.equals(codeField.getPrimaryKeyFlag()); + } + + ).collect(Collectors.toList()); + + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeInsertAndUpdateField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.base.common.swagger.SchemaEnum;"); + packageList.add("import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnumPrefix = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\""; + String checkEnum = checkEnumPrefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + + finalFieldMap.put("apiModelProperty", "@SchemaEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + } else { + String prefix = "@Schema(description = \"" + codeField.getLabel() + "\""; + String apiModelProperty = prefix + (field.getRequiredFlag() ? ", requiredMode = Schema.RequiredMode.REQUIRED)" : ")"); + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.v3.oas.annotations.media.Schema;"); + + if (Boolean.TRUE.equals(field.getRequiredFlag())) { + String notEmptyPrefix = "String".equals(codeField.getJavaType()) ? "@NotBlank" : "@NotNull"; + finalFieldMap.put("notEmpty", "\n " + notEmptyPrefix + "(message = \"" + codeField.getLabel() + " 不能为空\")"); + packageList.add("String".equals(codeField.getJavaType()) ? "import javax.validation.constraints.NotBlank;" : "import javax.validation.constraints.NotNull;"); + } + } + + + //字典 + if (SmartStringUtil.isNotEmpty(codeField.getDict())) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictDataDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer;"); + } + + //文件上传 + if (CodeFrontComponentEnum.FILE_UPLOAD.equalsValue(field.getFrontComponent())) { + finalFieldMap.put("file", "\n @JsonDeserialize(using = FileKeyVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java new file mode 100644 index 0000000..45844fe --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java @@ -0,0 +1,107 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeTableField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class VOVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + Map fieldMap = getFieldMap(form); + List updateFieldList = form.getTableFields().stream().filter(e -> Boolean.TRUE.equals(e.getShowFlag())).collect(Collectors.toList()); + + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.vo"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeTableField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 CodeTableField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.base.common.swagger.SchemaEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + finalFieldMap.put("apiModelProperty", "@SchemaEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("isEnum", true); + + } else { + String apiModelProperty = "@Schema(description = \"" + codeField.getLabel() + "\")"; + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.v3.oas.annotations.media.Schema;"); + } + + //文件上传 + if (isFile(field.getColumnName(), form)) { + finalFieldMap.put("file", "\n @JsonSerialize(using = FileKeyVoSerializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonSerialize;"); + packageList.add("import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ApiVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ApiVariableService.java new file mode 100644 index 0000000..0a98179 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ApiVariableService.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.front; + +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.*; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class ApiVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + return variablesMap; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ConstVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ConstVariableService.java new file mode 100644 index 0000000..0f49467 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ConstVariableService.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.front; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.CaseFormat; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class ConstVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + List> enumList = new ArrayList<>(); + List enumFiledList = form.getFields().stream().filter(e -> SmartStringUtil.isNotBlank(e.getEnumName())).collect(Collectors.toList()); + for (CodeField codeField : enumFiledList) { + Map beanToMap = BeanUtil.beanToMap(codeField); + String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName()); + beanToMap.put("upperUnderscoreEnum", upperUnderscoreEnum); + enumList.add(beanToMap); + } + variablesMap.put("enumList", enumList); + return variablesMap; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/FormVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/FormVariableService.java new file mode 100644 index 0000000..85b2354 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/FormVariableService.java @@ -0,0 +1,84 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.front; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.CaseFormat; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.*; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class FormVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + List> fieldsVariableList = new ArrayList<>(); + List fieldList = form.getInsertAndUpdate().getFieldList(); + + HashSet frontImportSet = new HashSet<>(); + + for (CodeInsertAndUpdateField field : fieldList) { + // 不存在 添加 和 更新 + if (!(field.getInsertFlag() || field.getUpdateFlag())) { + continue; + } + + Map objectMap = BeanUtil.beanToMap(field); + + CodeField codeField = getCodeFieldByColumnName(field.getColumnName(), form); + if (codeField == null) { + continue; + } + objectMap.put("label", codeField.getLabel()); + objectMap.put("fieldName", codeField.getFieldName()); + objectMap.put("dict", codeField.getDict()); + + if (SmartStringUtil.isNotBlank(codeField.getEnumName())) { + String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName()); + objectMap.put("upperUnderscoreEnum", upperUnderscoreEnum); + } + + fieldsVariableList.add(objectMap); + + if (CodeFrontComponentEnum.ENUM_SELECT.equalsValue(field.getFrontComponent())) { + frontImportSet.add("import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';"); + } + + if (CodeFrontComponentEnum.BOOLEAN_SELECT.equalsValue(field.getFrontComponent())) { + frontImportSet.add("import BooleanSelect from '/@/components/framework/boolean-select/index.vue';"); + } + + if (CodeFrontComponentEnum.DICT_SELECT.equalsValue(field.getFrontComponent())) { + frontImportSet.add("import DictSelect from '/@/components/support/dict-select/index.vue';"); + frontImportSet.add("import { DICT_CODE_ENUM } from '/@/constants/support/dict-const.js';"); + } + + if (CodeFrontComponentEnum.FILE_UPLOAD.equalsValue(field.getFrontComponent())) { + frontImportSet.add("import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';"); + frontImportSet.add("import FileUpload from '/@/components/support/file-upload/index.vue';"); + } + } + + variablesMap.put("formFields", fieldsVariableList); + variablesMap.put("frontImportList", new ArrayList<>(frontImportSet)); + + return variablesMap; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ListVariableService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ListVariableService.java new file mode 100644 index 0000000..0fee735 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ListVariableService.java @@ -0,0 +1,114 @@ +package net.lab1024.sa.base.module.support.codegenerator.service.variable.front; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.CaseFormat; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.base.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; +import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeQueryField; +import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeTableField; +import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class ListVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + + HashSet frontImportSet = new HashSet<>(); + frontImportSet.add("import " + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, form.getBasic().getModuleName()) + "Form from './" + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, form.getBasic().getModuleName()) + "-form.vue';"); + + // 查询参数 + List> queryVariable = new ArrayList<>(); + List queryFields = form.getQueryFields(); + + for (CodeQueryField queryField : queryFields) { + Map objectMap = BeanUtil.beanToMap(queryField); + + CodeField codeField = getCodeFieldByColumnName(queryField.getColumnNameList().get(0), form); + + if (CodeQueryFieldQueryTypeEnum.ENUM.equalsValue(queryField.getQueryTypeEnum()) && SmartStringUtil.isNotBlank(codeField.getEnumName())) { + String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName()); + objectMap.put("frontEnumName", upperUnderscoreEnum); + frontImportSet.add("import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';"); + } + + if (CodeQueryFieldQueryTypeEnum.DICT.equalsValue(queryField.getQueryTypeEnum())) { + objectMap.put("dict", codeField.getDict()); + frontImportSet.add("import DictSelect from '/@/components/support/dict-select/index.vue';"); + } + + if (CodeQueryFieldQueryTypeEnum.DATE_RANGE.equalsValue(queryField.getQueryTypeEnum())) { + frontImportSet.add("import { defaultTimeRanges } from '/@/lib/default-time-ranges';"); + } + queryVariable.add(objectMap); + } + + // 表格列表 + List> listVariable = new ArrayList<>(); + // 过滤掉不显示的字段 + List tableFields = form.getTableFields().stream().filter(CodeTableField::getShowFlag).collect(Collectors.toList()); + + for (CodeTableField tableField : tableFields) { + Map objectMap = BeanUtil.beanToMap(tableField); + objectMap.put("fieldName", tableField.getFieldName()); + + CodeField codeField = getCodeFieldByColumnName(tableField.getColumnName(), form); + if (codeField == null) { + continue; + } + + // 是否存在枚举 + if (SmartStringUtil.isNotBlank(codeField.getEnumName())) { + String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName()); + objectMap.put("frontEnumPlugin", "$smartEnumPlugin.getDescByValue('" + upperUnderscoreEnum + "', text)"); + } + + // 是否存在字典 + if (SmartStringUtil.isNotBlank(codeField.getDict())) { + objectMap.put("dict", codeField.getDict()); + frontImportSet.add("import { DICT_CODE_ENUM } from '/@/constants/support/dict-const.js';"); + frontImportSet.add("import DictLabel from '/@/components/support/dict-label/index.vue';"); + } + + CodeInsertAndUpdateField codeInsertAndUpdateField = form.getInsertAndUpdate().getFieldList().stream().filter(e -> SmartStringUtil.equals(tableField.getColumnName(), e.getColumnName())).findFirst().orElse(null); + if (codeInsertAndUpdateField == null) { + continue; + } + + // 是否存在上传组件 + if (CodeFrontComponentEnum.FILE_UPLOAD.equalsValue(codeInsertAndUpdateField.getFrontComponent())) { + objectMap.put("frontComponent", codeInsertAndUpdateField.getFrontComponent()); + frontImportSet.add("import FilePreview from '/@/components/support/file-preview/index.vue';"); + } + + listVariable.add(objectMap); + } + + variablesMap.put("queryFields", queryVariable); + variablesMap.put("listFields", listVariable); + variablesMap.put("frontImportList", new ArrayList<>(frontImportSet)); + + return variablesMap; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/util/CodeGeneratorTool.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/util/CodeGeneratorTool.java new file mode 100644 index 0000000..b3c0be3 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/codegenerator/util/CodeGeneratorTool.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.module.support.codegenerator.util; + +import com.google.common.base.CaseFormat; +import net.lab1024.sa.base.common.constant.StringConst; + +/** + * 代码生成 velocity 工具类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/30 19:02:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +public class CodeGeneratorTool { + + /** + * 小写驼峰,转为大写驼峰 + */ + public String lowerCamel2UpperCamel(String str) { + if (str == null) { + return StringConst.EMPTY; + } + return CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, str); + } + + /** + * 小写驼峰,转为小写中划线 + */ + public String lowerCamel2LowerHyphen(String str) { + if (str == null) { + return StringConst.EMPTY; + } + return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, str); + } + + + /** + * 去掉 注释 枚举类型 + */ + public String removeEnumDesc(String str) { + if (str == null) { + return StringConst.EMPTY; + } + + int index = str.indexOf("["); + if (index == -1) { + index = str.indexOf("【"); + } + + if (index == -1) { + return str; + } + + return str.substring(0, index - 1); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigController.java new file mode 100644 index 0000000..f40cdaa --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigController.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.config; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.config.domain.ConfigVO; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.CONFIG) +@RestController +public class ConfigController extends SupportBaseController { + + @Resource + private ConfigService configService; + + @Operation(summary = "查询配置详情 @author 卓大") + @GetMapping("/config/queryByKey") + public ResponseDTO queryByKey(@RequestParam String configKey) { + return ResponseDTO.ok(configService.getConfig(configKey)); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigDao.java new file mode 100644 index 0000000..bb525b8 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigDao.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.base.module.support.config; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.config.domain.ConfigEntity; +import net.lab1024.sa.base.module.support.config.domain.ConfigQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 系统参数配置 t_config Dao层 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface ConfigDao extends BaseMapper { + + /** + * 分页查询系统配置 + * + */ + List queryByPage(Page page, @Param("query") ConfigQueryForm queryForm); + + /** + * 根据key查询获取数据 + * + */ + ConfigEntity selectByKey(String key); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigKeyEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigKeyEnum.java new file mode 100644 index 0000000..da4514d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigKeyEnum.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.config; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 系统配置常量类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Getter +@AllArgsConstructor +public enum ConfigKeyEnum implements BaseEnum { + + /** + * 万能密码 + */ + SUPER_PASSWORD("super_password", "万能密码"), + + LEVEL3_PROTECT_CONFIG("level3_protect_config", "三级等保配置"), + ; + + private final String value; + + private final String desc; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigService.java new file mode 100644 index 0000000..3522dea --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/ConfigService.java @@ -0,0 +1,187 @@ +package net.lab1024.sa.base.module.support.config; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.constant.ReloadConst; +import net.lab1024.sa.base.module.support.config.domain.*; +import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 系统配置业务类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class ConfigService { + + /** + * 一个简单的系统配置缓存 + */ + private final ConcurrentHashMap CONFIG_CACHE = new ConcurrentHashMap<>(); + + @Resource + private ConfigDao configDao; + + @SmartReload(ReloadConst.CONFIG_RELOAD) + public void configReload(String param) { + this.loadConfigCache(); + } + + /** + * 初始化系统设置缓存 + */ + @PostConstruct + private void loadConfigCache() { + CONFIG_CACHE.clear(); + List entityList = configDao.selectList(null); + if (CollectionUtils.isEmpty(entityList)) { + return; + } + entityList.forEach(entity -> this.CONFIG_CACHE.put(entity.getConfigKey().toLowerCase(), entity)); + log.info("################# 系统配置缓存初始化完毕:{} ###################", CONFIG_CACHE.size()); + } + + /** + * 刷新系统设置缓存 + */ + private void refreshConfigCache(Long configId) { + // 重新查询 加入缓存 + ConfigEntity configEntity = configDao.selectById(configId); + if (null == configEntity) { + return; + } + this.CONFIG_CACHE.put(configEntity.getConfigKey().toLowerCase(), configEntity); + } + + /** + * 分页查询系统配置 + * + */ + public ResponseDTO> queryConfigPage(ConfigQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List entityList = configDao.queryByPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, entityList, ConfigVO.class); + return ResponseDTO.ok(pageResult); + } + + /** + * 查询配置缓存 + * + */ + public ConfigVO getConfig(ConfigKeyEnum configKey) { + return this.getConfig(configKey.getValue()); + } + + /** + * 查询配置缓存 + * + */ + public ConfigVO getConfig(String configKey) { + if (StrUtil.isBlank(configKey)) { + return null; + } + ConfigEntity entity = this.CONFIG_CACHE.get(configKey.toLowerCase()); + return SmartBeanUtil.copy(entity, ConfigVO.class); + } + + /** + * 查询配置缓存参数 + * + */ + public String getConfigValue(ConfigKeyEnum configKey) { + ConfigVO config = this.getConfig(configKey); + return config == null ? null : config.getConfigValue(); + } + + /** + * 根据参数key查询 并转换为对象 + * + */ + public T getConfigValue2Obj(ConfigKeyEnum configKey, Class clazz) { + String configValue = this.getConfigValue(configKey); + return JSON.parseObject(configValue, clazz); + } + + /** + * 添加系统配置 + * + */ + public ResponseDTO add(ConfigAddForm configAddForm) { + ConfigEntity entity = configDao.selectByKey(configAddForm.getConfigKey()); + if (null != entity) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST); + } + entity = SmartBeanUtil.copy(configAddForm, ConfigEntity.class); + configDao.insert(entity); + + // 刷新缓存 + this.refreshConfigCache(entity.getConfigId()); + return ResponseDTO.ok(); + } + + /** + * 更新系统配置 + * + */ + public ResponseDTO updateConfig(ConfigUpdateForm updateDTO) { + Long configId = updateDTO.getConfigId(); + ConfigEntity entity = configDao.selectById(configId); + if (null == entity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + ConfigEntity alreadyEntity = configDao.selectByKey(updateDTO.getConfigKey()); + if (null != alreadyEntity && !Objects.equals(configId, alreadyEntity.getConfigId())) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, "config key 已存在"); + } + + // 更新数据 + entity = SmartBeanUtil.copy(updateDTO, ConfigEntity.class); + configDao.updateById(entity); + + // 刷新缓存 + this.refreshConfigCache(configId); + return ResponseDTO.ok(); + } + + /** + * 更新系统配置 + * + */ + public ResponseDTO updateValueByKey(ConfigKeyEnum key, String value) { + ConfigVO config = this.getConfig(key); + if (null == config) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 更新数据 + Long configId = config.getConfigId(); + ConfigEntity entity = new ConfigEntity(); + entity.setConfigId(configId); + entity.setConfigValue(value); + configDao.updateById(entity); + + // 刷新缓存 + this.refreshConfigCache(configId); + return ResponseDTO.ok(); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigAddForm.java new file mode 100644 index 0000000..fb4836a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigAddForm.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.module.support.config.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 添加配置表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ConfigAddForm { + + @Schema(description = "参数key") + @NotBlank(message = "参数key不能为空") + @Length(max = 255, message = "参数key最多255个字符") + private String configKey; + + @Schema(description = "参数的值") + @NotBlank(message = "参数的值不能为空") + @Length(max = 60000, message = "参数的值最多60000个字符") + private String configValue; + + @Schema(description = "参数名称") + @NotBlank(message = "参数名称不能为空") + @Length(max = 255, message = "参数名称最多255个字符") + private String configName; + + @Schema(description = "备注") + @Length(max = 255, message = "备注最多255个字符") + private String remark; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigEntity.java new file mode 100644 index 0000000..1f8f696 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigEntity.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.module.support.config.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 系统配置参数 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_config") +public class ConfigEntity { + + @TableId(type = IdType.AUTO) + private Long configId; + + /** + * 参数key + */ + private String configKey; + + /** + * 参数的值 + */ + private String configValue; + + /** + * 参数名称 + */ + private String configName; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigQueryForm.java new file mode 100644 index 0000000..db5b8a1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigQueryForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.base.module.support.config.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +/** + * 分页查询 系统配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ConfigQueryForm extends PageParam { + + @Schema(description = "参数KEY") + @Length(max = 50, message = "参数Key最多50字符") + private String configKey; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigUpdateForm.java new file mode 100644 index 0000000..3ef5990 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.base.module.support.config.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 配置更新表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ConfigUpdateForm extends ConfigAddForm { + + @Schema(description = "configId") + @NotNull(message = "configId不能为空") + private Long configId; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigVO.java new file mode 100644 index 0000000..f80e560 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/config/domain/ConfigVO.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.module.support.config.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 配置信息 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ConfigVO { + @Schema(description = "主键") + private Long configId; + + @Schema(description = "参数key") + private String configKey; + + @Schema(description = "参数的值") + private String configValue; + + @Schema(description = "参数名称") + private String configName; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "上次修改时间") + private LocalDateTime updateTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/DataMasking.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/DataMasking.java new file mode 100644 index 0000000..c3847d7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/DataMasking.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.base.module.support.datamasking; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import net.lab1024.sa.base.common.json.serializer.DataMaskingSerializer; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 脱敏注解 + * + * @author 罗伊 + * @description: + * @date 2024/7/21 4:39 下午 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@JacksonAnnotationsInside +@JsonSerialize(using = DataMaskingSerializer.class, nullsUsing = DataMaskingSerializer.class) +public @interface DataMasking { + + DataMaskingTypeEnum value() default DataMaskingTypeEnum.COMMON; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/DataMaskingTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/DataMaskingTypeEnum.java new file mode 100644 index 0000000..7df897a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/DataMaskingTypeEnum.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.base.module.support.datamasking; + +import cn.hutool.core.util.DesensitizedUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 脱敏数据类型 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/8/1 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ + +@AllArgsConstructor +@Getter +public enum DataMaskingTypeEnum { + + COMMON(null, "通用"), + PHONE(DesensitizedUtil.DesensitizedType.MOBILE_PHONE, "手机号"), + CHINESE_NAME(DesensitizedUtil.DesensitizedType.CHINESE_NAME, "中文名"), + ID_CARD(DesensitizedUtil.DesensitizedType.ID_CARD, "身份证号"), + FIXED_PHONE(DesensitizedUtil.DesensitizedType.FIXED_PHONE, "座机号"), + ADDRESS(DesensitizedUtil.DesensitizedType.ADDRESS, "地址"), + EMAIL(DesensitizedUtil.DesensitizedType.EMAIL, "电子邮件"), + PASSWORD(DesensitizedUtil.DesensitizedType.PASSWORD, "密码"), + CAR_LICENSE(DesensitizedUtil.DesensitizedType.CAR_LICENSE, "中国大陆车牌"), + BANK_CARD(DesensitizedUtil.DesensitizedType.BANK_CARD, "银行卡"), + USER_ID(DesensitizedUtil.DesensitizedType.USER_ID, "用户id"); + + + + private DesensitizedUtil.DesensitizedType type; + + private String desc; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/SmartDataMaskingUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/SmartDataMaskingUtil.java new file mode 100644 index 0000000..4443da4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datamasking/SmartDataMaskingUtil.java @@ -0,0 +1,216 @@ +package net.lab1024.sa.base.module.support.datamasking; + +import cn.hutool.core.util.DesensitizedUtil; +import cn.hutool.core.util.StrUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 脱敏工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2024-07-23 21:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class SmartDataMaskingUtil { + + /** + * 类 加注解字段缓存 + */ + private static final ConcurrentHashMap, List> fieldMap = new ConcurrentHashMap<>(); + + public static String dataMasking(String value) { + if (StringUtils.isBlank(value)) { + return value; + } + + if (value.length() < 4) { + return StrUtil.hide(value, 0, value.length()); + } + + int valueLength = value.length(); + int startHideIndex = getHideStartIndex(valueLength); + int endHideIndex = getHideEndIndex(valueLength); + return StrUtil.hide(value, startHideIndex, endHideIndex); + } + + public static Object dataMasking(Object value, DataMaskingTypeEnum dataType) { + + if (value == null) { + return null; + } + + if (dataType == null) { + return dataMasking(String.valueOf(value)); + } + + switch (dataType) { + case PHONE: + return DesensitizedUtil.mobilePhone(String.valueOf(value)); + case CHINESE_NAME: + return DesensitizedUtil.chineseName(String.valueOf(value)); + case ID_CARD: + return DesensitizedUtil.idCardNum(String.valueOf(value), 6, 2); + case FIXED_PHONE: + return DesensitizedUtil.fixedPhone(String.valueOf(value)); + case ADDRESS: + return StrUtil.hide(String.valueOf(value), 6, String.valueOf(value).length() - 1); + case EMAIL: + return DesensitizedUtil.email(String.valueOf(value)); + case PASSWORD: + return DesensitizedUtil.password(String.valueOf(value)); + case CAR_LICENSE: + return DesensitizedUtil.carLicense(String.valueOf(value)); + case BANK_CARD: + return DesensitizedUtil.bankCard(String.valueOf(value)); + case USER_ID: + return DesensitizedUtil.userId(); + default: + return dataMasking(String.valueOf(value)); + } + } + + /** + * 批量脱敏 + */ + public static void dataMasking(Collection objectList) throws IntrospectionException, InvocationTargetException, IllegalAccessException { + if (CollectionUtils.isEmpty(objectList)) { + return; + } + + for (T object : objectList) { + dataMasking(object); + } + } + + + /** + * 单个脱敏 + */ + public static void dataMasking(T object) throws IntrospectionException, InvocationTargetException, IllegalAccessException { + Class tClass = object.getClass(); + List fieldList = getField(object); + for (Field field : fieldList) { + field.setAccessible(true); + String fieldValue = ""; + try { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), tClass); + Method getMethod = pd.getReadMethod(); + Object value = getMethod.invoke(object); + if (value != null) { + fieldValue = value.toString(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + if (StringUtils.isBlank(fieldValue)) { + continue; + } + int valueLength = fieldValue.length(); + int startHideIndex = getHideStartIndex(valueLength); + int endHideIndex = getHideEndIndex(valueLength); + try { + field.set(object, StrUtil.hide(fieldValue, startHideIndex, endHideIndex)); + } catch (Exception e1) { + throw new RuntimeException(e1); + } + } + } + + private static int getHideStartIndex(int totalLength) { + if (totalLength <= 4) { + return 1; + } else if (totalLength <= 6) { + return 1; + } else if (totalLength <= 10) { + return 2; + } else if (totalLength <= 18) { + return 3; + } else if (totalLength <= 27) { + return 5; + } else if (totalLength <= 34) { + return 7; + } else if (totalLength <= 41) { + return 9; + } else { + return 15; + } + } + + private static int getHideEndIndex(int totalLength) { + if (totalLength <= 4) { + return totalLength - 1; + } else if (totalLength <= 6) { + return totalLength - 2; + } else if (totalLength <= 10) { + return totalLength - 2; + } else if (totalLength <= 18) { + return totalLength - 4; + } else if (totalLength <= 27) { + return totalLength - 6; + } else if (totalLength <= 34) { + return totalLength - 8; + } else if (totalLength <= 41) { + return totalLength - 10; + } else { + return totalLength - 16; + } + } + + + public static List getField(Object object) throws IntrospectionException { + // 从缓存中查询 + Class tClass = object.getClass(); + List fieldList = fieldMap.get(tClass); + if (null != fieldList) { + return fieldList; + } + + // 这一段递归代码 是为了 从父类中获取属性 + Class tempClass = tClass; + fieldList = new ArrayList<>(); + while (tempClass != null) { + Field[] declaredFields = tempClass.getDeclaredFields(); + for (Field field : declaredFields) { + boolean stringField = false; + try { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), tClass); + Method getMethod = pd.getReadMethod(); + Type returnType = getMethod.getGenericReturnType(); + stringField = "java.lang.String".equals(returnType.getTypeName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (field.isAnnotationPresent(DataMasking.class) && stringField) { + field.setAccessible(true); + fieldList.add(field); + } + } + tempClass = tempClass.getSuperclass(); + } + fieldMap.put(tClass, fieldList); + return fieldList; + } + + public static void main(String[] args) { + System.out.println(dataMasking("a", null)); + System.out.println(dataMasking("ab", null)); + System.out.println(dataMasking("abc", null)); + System.out.println(dataMasking("abcd", null)); + System.out.println(dataMasking("abcde", null)); + } + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java new file mode 100644 index 0000000..c68dbdd --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.base.module.support.datatracer.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据变动字段注解 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldBigDecimal { + int scale() default 2; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldDict.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldDict.java new file mode 100644 index 0000000..6fefae2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldDict.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.base.module.support.datatracer.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字典的字段 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldDict { + + String dictCode(); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldEnum.java new file mode 100644 index 0000000..b46c574 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldEnum.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.base.module.support.datatracer.annoation; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字段枚举 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldEnum { + + Class enumClass() default BaseEnum.class; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldLabel.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldLabel.java new file mode 100644 index 0000000..4209e17 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldLabel.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.base.module.support.datatracer.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字段标签 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldLabel { + /** + * 本属性的注释信息 + * @return + */ + String value() default ""; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldSql.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldSql.java new file mode 100644 index 0000000..d373ebd --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldSql.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.base.module.support.datatracer.annoation; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 支持查询sql + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldSql { + + /** + * 关联字段名称 + * @return + */ + String relateColumn() default "id"; + + /** + * 关联显示的字段 + * @return + */ + String relateDisplayColumn() default ""; + /** + * 是否关联字段查询Mapper + * @return + */ + Class relateMapper() default BaseMapper.class; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerConst.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerConst.java new file mode 100644 index 0000000..b80fcd2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerConst.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.base.module.support.datatracer.constant; + +/** + * 常量 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class DataTracerConst { + + public static final String TAB = " "; + + public static final String SPLIT_LINE = "-----------------------------"; + + public static final String BLANK = " "; + public static final String SPLIT = ": "; + public static final String HTML_BR = "
"; + + public static final String INSERT = "新增"; + + public static final String DELETE = "删除"; + + public static final String UPDATE = "修改"; +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerTypeEnum.java new file mode 100644 index 0000000..b105b69 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerTypeEnum.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.base.module.support.datatracer.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 数据业务类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52- + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum DataTracerTypeEnum implements BaseEnum { + + /** + * 商品 + */ + GOODS(1, "商品"), + + /** + *通知公告 + */ + OA_NOTICE(2, "OA-通知公告"), + + /** + * 企业信息 + */ + OA_ENTERPRISE(3, "OA-企业信息"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/controller/DataTracerController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/controller/DataTracerController.java new file mode 100644 index 0000000..826df3b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/controller/DataTracerController.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.base.module.support.datatracer.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerQueryForm; +import net.lab1024.sa.base.module.support.datatracer.domain.vo.DataTracerVO; +import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 数据变动记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.DATA_TRACER) +@RestController +public class DataTracerController extends SupportBaseController { + + @Resource + private DataTracerService dataTracerService; + + @Operation(summary = "分页查询业务操作日志 - @author 卓大") + @PostMapping("/dataTracer/query") + public ResponseDTO> query(@Valid @RequestBody DataTracerQueryForm queryForm) { + return dataTracerService.query(queryForm); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/dao/DataTracerDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/dao/DataTracerDao.java new file mode 100644 index 0000000..9f467a7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/dao/DataTracerDao.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.datatracer.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.datatracer.domain.entity.DataTracerEntity; +import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerQueryForm; +import net.lab1024.sa.base.module.support.datatracer.domain.vo.DataTracerVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * dao: t_data_tracker + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface DataTracerDao extends BaseMapper { + + /** + * 操作记录查询 + * + */ + List selectRecord(@Param("dataId") Long dataId, @Param("dataType") Integer dataType); + + /** + * 分页查询 + * + */ + List query(Page page, @Param("query") DataTracerQueryForm queryForm); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/bo/DataTracerContentBO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/bo/DataTracerContentBO.java new file mode 100644 index 0000000..a129e96 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/bo/DataTracerContentBO.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.module.support.datatracer.domain.bo; + +import lombok.Data; + +import java.lang.reflect.Field; + +/** + * 变动内容 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class DataTracerContentBO { + + /** + * 变动字段 + */ + private Field field; + + /** + * 变动字段的值 + */ + private Object fieldValue; + + /** + * 变动字段描述 + */ + private String fieldDesc; + + /** + * 变动内容 + */ + private String fieldContent; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/entity/DataTracerEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/entity/DataTracerEntity.java new file mode 100644 index 0000000..3df5f7b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/entity/DataTracerEntity.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.base.module.support.datatracer.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; + +import java.time.LocalDateTime; + +/** + * 数据记录 实体 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_data_tracer") +public class DataTracerEntity { + + @TableId(type = IdType.AUTO) + private Long dataTracerId; + /** + * 数据id + */ + private Long dataId; + /** + * 业务类型 + * {@link DataTracerTypeEnum} + */ + private Integer type; + + /** + * 内容 + */ + private String content; + + /** + * diff 差异:旧的数据 + */ + private String diffOld; + + /** + * 差异:新的数据 + */ + private String diffNew; + + /** + * 扩展字段 + */ + private String extraData; + + /** + * 用户 + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 用户名 + */ + private String userName; + + /** + * 请求ip + */ + private String ip; + + /** + * 请求ip地区 + */ + private String ipRegion; + + /** + * 请求头 + */ + private String userAgent; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm.java new file mode 100644 index 0000000..2052ce0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.base.module.support.datatracer.domain.form; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; + +/** + * 数据变动表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DataTracerForm { + + /** + * 业务id + */ + private Long dataId; + + /** + * 业务类型 + */ + private DataTracerTypeEnum type; + + /** + * 操作内容 + */ + private String content; + + /** + * diff 差异:旧的数据 + */ + private String diffOld; + + /** + * 差异:新的数据 + */ + private String diffNew; + + /** + * 扩展字段 + */ + private String extraData; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerQueryForm.java new file mode 100644 index 0000000..8b6e2b0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.module.support.datatracer.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; + +import javax.validation.constraints.NotNull; + +/** + * 查询表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class DataTracerQueryForm extends PageParam { + + @SchemaEnum(DataTracerTypeEnum.class) + private Integer type; + + @Schema(description = "业务id") + @NotNull(message = "业务id不能为空") + private Long dataId; + + @Schema(description = "关键字") + private String keywords; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/vo/DataTracerVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/vo/DataTracerVO.java new file mode 100644 index 0000000..4e36cfc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/domain/vo/DataTracerVO.java @@ -0,0 +1,65 @@ +package net.lab1024.sa.base.module.support.datatracer.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; + +import java.time.LocalDateTime; + +/** + * 变动记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class DataTracerVO { + + @Schema(description = "日志id") + private Long dataTracerId; + + @Schema(description = "单据id") + private Long dataId; + + @SchemaEnum(value = DataTracerTypeEnum.class, desc = "业务类型") + private Integer type; + + @Schema(description = "操作内容") + private String content; + + @Schema(description = "diff 差异:旧的数据") + private String diffOld; + + @Schema(description = "差异:新的数据") + private String diffNew; + + @Schema(description = "扩展字段") + private String extraData; + + @Schema(description = "操作人") + private Long userId; + + @SchemaEnum(value = UserTypeEnum.class, desc = "用户类型") + private Integer userType; + + @Schema(description = "操作人名称") + private String userName; + + @Schema(description = "userAgent") + private String userAgent; + + @Schema(description = "ip") + private String ip; + + @Schema(description = "ip地区") + private String ipRegion; + + @Schema(description = "操作时间") + private LocalDateTime createTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/manager/DataTracerManger.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/manager/DataTracerManger.java new file mode 100644 index 0000000..6764151 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/manager/DataTracerManger.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.base.module.support.datatracer.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.base.module.support.datatracer.dao.DataTracerDao; +import net.lab1024.sa.base.module.support.datatracer.domain.entity.DataTracerEntity; +import org.springframework.stereotype.Service; + +/** + * manager层 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class DataTracerManger extends ServiceImpl { +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/service/DataTracerChangeContentService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/service/DataTracerChangeContentService.java new file mode 100644 index 0000000..201f7e7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/service/DataTracerChangeContentService.java @@ -0,0 +1,467 @@ +package net.lab1024.sa.base.module.support.datatracer.service; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.google.common.base.CaseFormat; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartBigDecimalUtil; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.datatracer.annoation.*; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.base.module.support.datatracer.domain.bo.DataTracerContentBO; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictDataVO; +import net.lab1024.sa.base.module.support.dict.service.DictService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 数据变更内容 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class DataTracerChangeContentService { + + @Resource + private ApplicationContext applicationContext; + @Resource + private DictService dictService; + /** + * 字段描述缓存 + */ + private final ConcurrentHashMap fieldDescCacheMap = new ConcurrentHashMap<>(); + + /** + * 类 加注解字段缓存 + */ + private final ConcurrentHashMap, List> fieldMap = new ConcurrentHashMap<>(); + + /** + * 数据批量对比 + * + * @param oldObjectList 原始对象列表 + * @param newObjectList 新的对象列表 + * @param Class类型 + * @return 变更内容 + */ + public String getChangeContent(List oldObjectList, List newObjectList) { + boolean valid = this.valid(oldObjectList, newObjectList); + if (!valid) { + return ""; + } + String operateType = this.getOperateType(oldObjectList, newObjectList); + String operateContent = ""; + if (DataTracerConst.INSERT.equals(operateType) || DataTracerConst.DELETE.equals(operateType)) { + operateContent = this.getObjectListContent(newObjectList); + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateType + ":" + operateContent; + } + if (DataTracerConst.UPDATE.equals(operateType)) { + return this.getUpdateContentList(oldObjectList, newObjectList); + } + return operateContent; + } + + + /** + * 解析多个对象的变更,删除,新增 + * oldObject 为空 ,newObject 不为空 为新增 + * oldObject 不为空 ,newObject 不空 为删除 + * 都不为空为编辑 + * + * @param oldObject 原始对象 + * @param newObject 新对象 + * @return 变更内容 + */ + public String getChangeContent(Object oldObject, Object newObject) { + boolean valid = this.valid(oldObject, newObject); + if (!valid) { + return ""; + } + String operateType = this.getOperateType(oldObject, newObject); + String operateContent = ""; + if (DataTracerConst.INSERT.equals(operateType) || DataTracerConst.DELETE.equals(operateType)) { + operateContent = this.getAddDeleteContent(newObject); + } + if (DataTracerConst.UPDATE.equals(operateType)) { + operateContent = this.getUpdateContent(oldObject, newObject); + } + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateContent; + } + + /** + * 解析单个bean的内容 + * + * @param object 普通对象 + * @return 单个内容 + */ + public String getChangeContent(Object object) { + return this.getAddDeleteContent(object); + } + + // ---------------------------- 以下 是 私有private 方法 ---------------------------- + + /** + * 获取新增或删除操作内容 + * + * @param object 新增或删除的对象 + */ + private String getAddDeleteContent(Object object) { + List fields = this.getField(object); + Map beanParseMap = this.fieldParse(object, fields); + return this.getAddDeleteContent(beanParseMap); + } + + /** + * 单个对象变动内容 + * + * @param oldObjectList 旧的对象列表 + * @param newObjectList 新的对象列表 + * @return 拼接后的内容 + */ + private String getUpdateContentList(List oldObjectList, List newObjectList) { + String oldContent = this.getObjectListContent(oldObjectList); + String newContent = this.getObjectListContent(newObjectList); + if (oldContent.equals(newContent)) { + return ""; + } + if (StringUtils.isEmpty(oldContent) && StringUtils.isEmpty(newContent)) { + return ""; + } + return "【原数据】:
" + oldContent + "
" + "【新数据】:
" + newContent; + } + + /** + * 解析批量bean的内容 + * + * @param objectList 对象列表 + * @return 单个内容 + */ + public String getChangeContent(List objectList) { + return this.getObjectListContent(objectList); + } + + /** + * 获取一个对象的内容信息 + * + * @param objectList 对象列表 + * @param 类型 + * @return 内容 + */ + private String getObjectListContent(List objectList) { + if (CollectionUtils.isEmpty(objectList)) { + return ""; + } + List fields = this.getField(objectList.get(0)); + List contentList = Lists.newArrayList(); + for (Object objItem : objectList) { + Map beanParseMap = this.fieldParse(objItem, fields); + contentList.add(this.getAddDeleteContent(beanParseMap)); + } + return StringUtils.join(contentList, "
"); + } + + private String getAddDeleteContent(Map beanParseMap) { + List contentList = new ArrayList<>(); + for (Entry entry : beanParseMap.entrySet()) { + DataTracerContentBO dataTracerContentBO = entry.getValue(); + boolean jsonFlag = JSONUtil.isTypeJSON(dataTracerContentBO.getFieldContent()); + String filedDesc = dataTracerContentBO.getFieldDesc(); + if (jsonFlag) { + contentList.add(filedDesc + "(请进入详情查看)"); + } else { + contentList.add(dataTracerContentBO.getFieldDesc() + ":" + dataTracerContentBO.getFieldContent()); + } + } + String operateContent = StringUtils.join(contentList, "
"); + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateContent; + } + + + /** + * 获取更新操作内容 + * + * @param oldObject 原始对象 + * @param newObject 新对象 + * @return + */ + private String getUpdateContent(T oldObject, T newObject) { + List fields = this.getField(oldObject); + List contentList = new ArrayList<>(); + Map oldBeanParseMap = this.fieldParse(oldObject, fields); + Map newBeanParseMap = this.fieldParse(newObject, fields); + //oldBeanParseMap与newBeanParseMap size一定相同 + for (Entry entry : oldBeanParseMap.entrySet()) { + String fieldName = entry.getKey(); + // 新旧对象内容 + DataTracerContentBO oldContentBO = entry.getValue(); + DataTracerContentBO newContentBO = newBeanParseMap.get(fieldName); + // fieldContent + String oldContent = oldContentBO == null || oldContentBO.getFieldContent() == null ? "" : oldContentBO.getFieldContent(); + String newContent = newContentBO == null || newContentBO.getFieldContent() == null ? "" : newContentBO.getFieldContent(); + + if (oldContent.equals(newContent)) { + continue; + } + String fieldDesc = oldContentBO.getFieldDesc(); + boolean jsonFlag = JSONUtil.isTypeJSON(oldContent) || JSONUtil.isTypeJSON(newContent); + if (jsonFlag) { + String content = fieldDesc + "【进入详情查看】"; + contentList.add(content); + continue; + } + String content = fieldDesc + ":" + "由【" + oldContent + "】变更为【" + newContent + "】"; + contentList.add(content); + } + if (CollectionUtils.isEmpty(contentList)) { + return ""; + } + String operateContent = StringUtils.join(contentList, "
"); + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateContent; + } + + + /** + * 接bean对象 + * + * @param object 对象 + * @param fields 字段 + * @return + */ + private Map fieldParse(Object object, List fields) { + if (fields == null || fields.isEmpty()) { + return new HashMap<>(); + } + //对象解析结果 + Map objectParse = new HashMap<>(16); + for (Field field : fields) { + field.setAccessible(true); + String desc = this.getFieldDesc(field); + if (StringUtils.isEmpty(desc)) { + continue; + } + DataTracerContentBO dataTracerContentBO = this.getFieldValue(field, object); + if (dataTracerContentBO != null) { + dataTracerContentBO.setFieldDesc(desc); + objectParse.put(field.getName(), dataTracerContentBO); + } + } + return objectParse; + } + + /** + * 获取字段值 + */ + private DataTracerContentBO getFieldValue(Field field, Object object) { + Object fieldValue = ""; + Class clazz = object.getClass(); + try { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz); + Method get = pd.getReadMethod(); + fieldValue = get.invoke(object); + } catch (Exception e) { + log.error("bean operate log: reflect field value error " + field.getName()); + return null; + } + if (fieldValue == null) { + return null; + } + + String fieldContent = ""; + DataTracerFieldEnum dataTracerFieldEnum = field.getAnnotation(DataTracerFieldEnum.class); + DataTracerFieldSql dataTracerFieldSql = field.getAnnotation(DataTracerFieldSql.class); + DataTracerFieldDict dataTracerFieldDict = field.getAnnotation(DataTracerFieldDict.class); + if (dataTracerFieldEnum != null) { + if (fieldValue instanceof Collection) { + fieldContent = SmartEnumUtil.getEnumDescByValueList((Collection) fieldValue, dataTracerFieldEnum.enumClass()); + } else { + fieldContent = SmartEnumUtil.getEnumDescByValue(fieldValue, dataTracerFieldEnum.enumClass()); + } + } else if (dataTracerFieldDict != null) { + DictDataVO dictData = dictService.getDictData(dataTracerFieldDict.dictCode(), fieldValue.toString()); + fieldContent = dictData == null ? fieldValue.toString() : dictData.getDataLabel(); + } else if (dataTracerFieldSql != null) { + fieldContent = this.getRelateDisplayValue(fieldValue, dataTracerFieldSql); + } else if (fieldValue instanceof Date) { + fieldContent = DateUtil.formatDateTime((Date) fieldValue); + } else if (fieldValue instanceof LocalDateTime) { + fieldContent = LocalDateTimeUtil.formatNormal((LocalDateTime) fieldValue); + } else if (fieldValue instanceof LocalDate) { + fieldContent = LocalDateTimeUtil.formatNormal((LocalDate) fieldValue); + } else if (fieldValue instanceof BigDecimal) { + DataTracerFieldBigDecimal dataTracerFieldBigDecimal = field.getAnnotation(DataTracerFieldBigDecimal.class); + if (dataTracerFieldBigDecimal != null) { + BigDecimal value = SmartBigDecimalUtil.setScale((BigDecimal) fieldValue, dataTracerFieldBigDecimal.scale()); + fieldContent = value.toString(); + } + } else { + fieldContent = JSON.toJSONString(fieldValue); + } + DataTracerContentBO dataTracerContentBO = new DataTracerContentBO(); + dataTracerContentBO.setField(field); + dataTracerContentBO.setFieldValue(fieldValue); + dataTracerContentBO.setFieldContent(fieldContent); + return dataTracerContentBO; + } + + /** + * 获取关联字段的显示值 + */ + private String getRelateDisplayValue(Object fieldValue, DataTracerFieldSql dataTracerFieldSql) { + Class relateMapper = dataTracerFieldSql.relateMapper(); + BaseMapper mapper = applicationContext.getBean(relateMapper); + if (mapper == null) { + return ""; + } + String relateFieldValue = fieldValue.toString(); + QueryWrapper qw = new QueryWrapper(); + qw.select(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, dataTracerFieldSql.relateDisplayColumn())); + qw.in(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, dataTracerFieldSql.relateColumn()), relateFieldValue); + List displayValue = mapper.selectObjs(qw); + if (CollectionUtils.isEmpty(displayValue)) { + return ""; + } + return SmartStringUtil.join(",", displayValue); + } + + /** + * 获取字段描述信息 优先 OperateField 没得话swagger判断 + */ + private String getFieldDesc(Field field) { + // 根据字段名称 从缓存中查询 + String fieldName = field.toGenericString(); + String desc = fieldDescCacheMap.get(fieldName); + if (null != desc) { + return desc; + } + DataTracerFieldLabel operateField = field.getAnnotation(DataTracerFieldLabel.class); + if (operateField != null) { + return operateField.value(); + } + fieldDescCacheMap.put(fieldName, desc); + return desc; + } + + /** + * 获取操作类型 + */ + private String getOperateType(Object oldObject, Object newObject) { + if (oldObject == null && newObject != null) { + return DataTracerConst.INSERT; + } + if (oldObject != null && newObject == null) { + return DataTracerConst.DELETE; + } + return DataTracerConst.UPDATE; + } + + /** + * 校验是否进行比对 + */ + private boolean valid(Object oldObject, Object newObject) { + if (oldObject == null && newObject == null) { + return false; + } + if (oldObject == null) { + return true; + } + if (newObject == null) { + return true; + } + String oldClass = oldObject.getClass().getName(); + String newClass = newObject.getClass().getName(); + return oldClass.equals(newClass); + } + + + /** + * 校验 + */ + private boolean valid(List oldObjectList, List newObjectList) { + if (CollectionUtils.isEmpty(oldObjectList) && CollectionUtils.isEmpty(newObjectList)) { + return false; + } + if (CollectionUtils.isEmpty(oldObjectList) && CollectionUtils.isNotEmpty(newObjectList)) { + return true; + } + if (CollectionUtils.isNotEmpty(oldObjectList) && CollectionUtils.isEmpty(newObjectList)) { + return true; + } + if (CollectionUtils.isNotEmpty(oldObjectList) && CollectionUtils.isNotEmpty(newObjectList)) { + T oldObject = oldObjectList.get(0); + T newObject = newObjectList.get(0); + String oldClass = oldObject.getClass().getName(); + String newClass = newObject.getClass().getName(); + return oldClass.equals(newClass); + } + return true; + } + + /** + * 查询 包含 file key 注解的字段 + * 使用缓存 + */ + private List getField(Object obj) { + // 从缓存中查询 + Class tClass = obj.getClass(); + List fieldList = fieldMap.get(tClass); + if (null != fieldList) { + return fieldList; + } + + // 这一段递归代码 是为了 从父类中获取属性 + Class tempClass = tClass; + fieldList = new ArrayList<>(); + while (tempClass != null) { + Field[] declaredFields = tempClass.getDeclaredFields(); + for (Field field : declaredFields) { + // 过虑出有注解字段 + if (!field.isAnnotationPresent(DataTracerFieldLabel.class)) { + continue; + } + field.setAccessible(true); + fieldList.add(field); + } + tempClass = tempClass.getSuperclass(); + } + fieldMap.put(tClass, fieldList); + return fieldList; + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/service/DataTracerService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/service/DataTracerService.java new file mode 100644 index 0000000..11d4d61 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/datatracer/service/DataTracerService.java @@ -0,0 +1,227 @@ +package net.lab1024.sa.base.module.support.datatracer.service; + + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartIpUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.base.module.support.datatracer.dao.DataTracerDao; +import net.lab1024.sa.base.module.support.datatracer.domain.entity.DataTracerEntity; +import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerForm; +import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerQueryForm; +import net.lab1024.sa.base.module.support.datatracer.domain.vo.DataTracerVO; +import net.lab1024.sa.base.module.support.datatracer.manager.DataTracerManger; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 数据变动记录 Service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class DataTracerService { + + @Resource + private DataTracerDao dataTracerDao; + + @Resource + private DataTracerManger dataTracerManger; + + @Resource + private DataTracerChangeContentService dataTracerChangeContentService; + + /** + * 获取变更内容 + * + * @param object + * @return + */ + public String getChangeContent(Object object) { + return dataTracerChangeContentService.getChangeContent(object); + } + + /** + * 获取变更内容 + */ + public String getChangeContent(Object oldObject, Object newObject) { + return dataTracerChangeContentService.getChangeContent(oldObject, newObject); + } + + + /** + * 获取变更内容 + */ + public String getChangeContent(List oldObjectList, List newObjectList) { + return dataTracerChangeContentService.getChangeContent(oldObjectList, newObjectList); + } + + + /** + * 保存【修改】数据变动记录 + * + * @param dataId + * @param type + */ + public void update(Long dataId, DataTracerTypeEnum type, Object oldObject, Object newObject) { + DataTracerForm form = DataTracerForm.builder() + .dataId(dataId) + .type(type) + .content(dataTracerChangeContentService.getChangeContent(oldObject, newObject)) + .build(); + this.addTrace(form); + } + + + /** + * 保存【新增】数据变动记录 + * + * @param dataId + * @param type + */ + public void insert(Long dataId, DataTracerTypeEnum type) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(DataTracerConst.INSERT).build(); + this.addTrace(form); + } + + /** + * 保存【删除】数据变动记录 + * + * @param dataId + * @param type + */ + public void delete(Long dataId, DataTracerTypeEnum type) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(DataTracerConst.DELETE).build(); + this.addTrace(form); + } + + /** + * 保存【删除】数据变动记录 + * + * @param dataId + * @param type + */ + public void delete(Long dataId, DataTracerTypeEnum type, Object object) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(DataTracerConst.DELETE).build(); + this.addTrace(form); + } + + /** + * 保存【批量删除】数据变动记录 + * + * @param dataIdList + * @param type + */ + public void batchDelete(List dataIdList, DataTracerTypeEnum type) { + if (CollectionUtils.isEmpty(dataIdList)) { + return; + } + + this.addTraceList(dataIdList.stream().map(e -> DataTracerForm.builder() + .dataId(e) + .type(type) + .content(DataTracerConst.DELETE) + .build()) + .collect(Collectors.toList()) + ); + } + + /** + * 保存数据变动记录 + * + * @param dataId + * @param type + * @param content + */ + public void addTrace(Long dataId, DataTracerTypeEnum type, String content) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(content).build(); + this.addTrace(form); + } + + /** + * 保存数据变动记录 + */ + public void addTrace(DataTracerForm tracerForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + this.addTrace(tracerForm, requestUser); + } + + + /** + * 保存数据变动记录 + */ + public void addTrace(DataTracerForm tracerForm, RequestUser requestUser) { + DataTracerEntity tracerEntity = SmartBeanUtil.copy(tracerForm, DataTracerEntity.class); + tracerEntity.setType(tracerForm.getType().getValue()); + if (requestUser != null) { + tracerEntity.setIp(requestUser.getIp()); + tracerEntity.setIpRegion(SmartIpUtil.getRegion(requestUser.getIp())); + tracerEntity.setUserAgent(requestUser.getUserAgent()); + tracerEntity.setUserId(requestUser.getUserId()); + tracerEntity.setUserType(requestUser.getUserType().getValue()); + tracerEntity.setUserName(requestUser.getUserName()); + } + dataTracerManger.save(tracerEntity); + } + + /** + * 批量保存数据变动记录 + */ + public void addTraceList(List tracerFormList) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + this.addTraceList(tracerFormList, requestUser); + } + + /** + * 批量保存数据变动记录 + */ + public void addTraceList(List tracerFormList, RequestUser requestUser) { + if (CollectionUtils.isEmpty(tracerFormList)) { + return; + } + + List tracerEntityList = tracerFormList.stream().map(e -> { + DataTracerEntity tracerEntity = SmartBeanUtil.copy(e, DataTracerEntity.class); + tracerEntity.setType(e.getType().getValue()); + tracerEntity.setIp(requestUser.getIp()); + tracerEntity.setIpRegion(SmartIpUtil.getRegion(requestUser.getIp())); + tracerEntity.setUserAgent(requestUser.getUserAgent()); + tracerEntity.setUserId(requestUser.getUserId()); + tracerEntity.setUserType(requestUser.getUserType().getValue()); + tracerEntity.setUserName(requestUser.getUserName()); + return tracerEntity; + }).collect(Collectors.toList()); + dataTracerManger.saveBatch(tracerEntityList); + } + + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public ResponseDTO> query(DataTracerQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = dataTracerDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return ResponseDTO.ok(pageResult); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/dao/DictDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/dao/DictDao.java new file mode 100644 index 0000000..b53bdf0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/dao/DictDao.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.base.module.support.dict.dao; + +import java.util.List; + +import net.lab1024.sa.base.module.support.dict.domain.entity.DictEntity; +import net.lab1024.sa.base.module.support.dict.domain.form.DictQueryForm; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 数据字典 Dao + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Mapper +@Component +public interface DictDao extends BaseMapper { + + /** + * 分页 查询 + */ + List queryPage(Page page, @Param("queryForm") DictQueryForm queryForm); + + /** + * 根据 dictCode 去查询 + */ + DictEntity selectByCode(@Param("code") String code); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/dao/DictDataDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/dao/DictDataDao.java new file mode 100644 index 0000000..f02492b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/dao/DictDataDao.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.module.support.dict.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.dict.domain.entity.DictDataEntity; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictDataVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 字典数据表 Dao + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 23:12:59 + * @Copyright 1024创新实验室 + */ + +@Mapper +@Component +public interface DictDataDao extends BaseMapper { + + List queryByDictId(@Param("dictId") Long dictId); + + List selectByDictDataIds(@Param("dictDataIdList") Collection dictDataIds); + + DictDataEntity selectByDictIdAndValue(@Param("dictId") Long dictId, @Param("dataValue") String dataValue); + + List getAll(); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/entity/DictDataEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/entity/DictDataEntity.java new file mode 100644 index 0000000..61b25b3 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/entity/DictDataEntity.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.base.module.support.dict.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 字典数据表 实体类 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 23:12:59 + * @Copyright 1024创新实验室 + */ + +@Data +@TableName("t_dict_data") +public class DictDataEntity { + + /** + * 字典数据id + */ + @TableId(type = IdType.AUTO) + private Long dictDataId; + + /** + * 字典id + */ + private Long dictId; + + /** + * 字典项值 + */ + private String dataValue; + + /** + * 字典项显示名称 + */ + private String dataLabel; + + /** + * 备注 + */ + private String remark; + + /** + * 排序(越大越靠前) + */ + private Integer sortOrder; + + /** + * 禁用状态 + */ + private Boolean disabledFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/entity/DictEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/entity/DictEntity.java new file mode 100644 index 0000000..0dc5d36 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/entity/DictEntity.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.base.module.support.dict.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 数据字典 实体类 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Data +@TableName("t_dict") +public class DictEntity { + + /** + * 字典id + */ + @TableId(type = IdType.AUTO) + private Long dictId; + + /** + * 字典名字 + */ + private String dictName; + + /** + * 字典编码 + */ + private String dictCode; + + /** + * 字典备注 + */ + private String remark; + + /** + * 禁用状态 + */ + private Boolean disabledFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictAddForm.java new file mode 100644 index 0000000..3e8f032 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictAddForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.dict.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotBlank; + +import lombok.Data; + +/** + * 数据字典 新建表单 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Data +public class DictAddForm { + + @Schema(description = "字典名字", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "字典名字 不能为空") + private String dictName; + + @Schema(description = "字典编码", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "字典编码 不能为空") + private String dictCode; + + @Schema(description = "字典备注") + private String remark; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictDataAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictDataAddForm.java new file mode 100644 index 0000000..faf1ed6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictDataAddForm.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.module.support.dict.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 字典数据表 新建表单 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 23:12:59 + * @Copyright 1024创新实验室 + */ + +@Data +public class DictDataAddForm { + + @Schema(description = "字典id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "字典id 不能为空") + private Long dictId; + + @Schema(description = "字典项值", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "字典项值 不能为空") + private String dataValue; + + @Schema(description = "字典项显示名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "字典项显示名称 不能为空") + private String dataLabel; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序(越大越靠前)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "排序(越大越靠前) 不能为空") + private Integer sortOrder; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictDataUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictDataUpdateForm.java new file mode 100644 index 0000000..48c1dd6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictDataUpdateForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.dict.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 字典数据表 更新表单 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 23:12:59 + * @Copyright 1024创新实验室 + */ + +@Data +public class DictDataUpdateForm extends DictDataAddForm { + + @Schema(description = "字典数据id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "字典数据id 不能为空") + private Long dictDataId; + + @Schema(description = "字典数据编码", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "字典数据编码 不能为空") + private String dictCode; + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictQueryForm.java new file mode 100644 index 0000000..5fb8da1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictQueryForm.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.base.module.support.dict.domain.form; + +import net.lab1024.sa.base.common.domain.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 数据字典 分页查询表单 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Data +@EqualsAndHashCode(callSuper = false) +public class DictQueryForm extends PageParam { + + @Schema(description = "关键字") + private String keywords; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictUpdateForm.java new file mode 100644 index 0000000..e032a77 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/form/DictUpdateForm.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.base.module.support.dict.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +/** + * 数据字典 更新表单 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Data +public class DictUpdateForm { + + @Schema(description = "字典id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "字典id 不能为空") + private Long dictId; + + @Schema(description = "字典名字", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "字典名字 不能为空") + private String dictName; + + @Schema(description = "字典编码", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "字典编码 不能为空") + private String dictCode; + + @Schema(description = "字典备注") + private String remark; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/vo/DictDataVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/vo/DictDataVO.java new file mode 100644 index 0000000..761799a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/vo/DictDataVO.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.base.module.support.dict.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 字典数据表 列表VO + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 23:12:59 + * @Copyright 1024创新实验室 + */ + +@Data +public class DictDataVO implements Serializable { + + @Schema(description = "字典数据id") + private Long dictDataId; + + @Schema(description = "字典id") + private Long dictId; + + @Schema(description = "字典编码") + private String dictCode; + + @Schema(description = "字典名字") + private String dictName; + + @Schema(description = "字典禁用状态") + private Boolean dictDisabledFlag; + + @Schema(description = "字典项值") + private String dataValue; + + @Schema(description = "字典项显示名称") + private String dataLabel; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序(越大越靠前)") + private Integer sortOrder; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/vo/DictVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/vo/DictVO.java new file mode 100644 index 0000000..4a9131c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/domain/vo/DictVO.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.base.module.support.dict.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.time.LocalDateTime; + +import lombok.Data; + +/** + * 数据字典 列表VO + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Data +public class DictVO { + + @Schema(description = "字典id") + private Long dictId; + + @Schema(description = "字典名字") + private String dictName; + + @Schema(description = "字典编码") + private String dictCode; + + @Schema(description = "字典备注") + private String remark; + + @Schema(description = "禁用状态") + private Boolean disabledFlag; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/manager/DictManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/manager/DictManager.java new file mode 100644 index 0000000..0669cc5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/manager/DictManager.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.base.module.support.dict.manager; + +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.constant.CacheKeyConst; +import net.lab1024.sa.base.module.support.dict.dao.DictDao; +import net.lab1024.sa.base.module.support.dict.dao.DictDataDao; +import net.lab1024.sa.base.module.support.dict.domain.entity.DictDataEntity; +import net.lab1024.sa.base.module.support.dict.domain.entity.DictEntity; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictDataVO; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 数据字典 缓存 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Service +public class DictManager { + + @Resource + private DictDao dictDao; + + @Resource + private DictDataDao dictDataDao; + + + /** + * 获取字典 + */ + @Cacheable(value = CacheKeyConst.Dict.DICT_DATA, key = "#dictCode + '_' + #dataValue") + public DictDataVO getDictData(String dictCode, String dataValue) { + DictEntity dictEntity = dictDao.selectByCode(dictCode); + if (dictEntity == null) { + return null; + } + + DictDataEntity dictDataEntity = dictDataDao.selectByDictIdAndValue(dictEntity.getDictId(), dataValue); + return SmartBeanUtil.copy(dictDataEntity, DictDataVO.class); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/service/DictService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/service/DictService.java new file mode 100644 index 0000000..156f411 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/dict/service/DictService.java @@ -0,0 +1,275 @@ +package net.lab1024.sa.base.module.support.dict.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.constant.CacheKeyConst; +import net.lab1024.sa.base.module.support.dict.dao.DictDao; +import net.lab1024.sa.base.module.support.dict.dao.DictDataDao; +import net.lab1024.sa.base.module.support.dict.domain.entity.DictDataEntity; +import net.lab1024.sa.base.module.support.dict.domain.entity.DictEntity; +import net.lab1024.sa.base.module.support.dict.domain.form.*; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictDataVO; +import net.lab1024.sa.base.module.support.dict.domain.vo.DictVO; +import net.lab1024.sa.base.module.support.dict.manager.DictManager; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 数据字典 Service + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2025-03-25 22:25:04 + * @Copyright 1024创新实验室 + */ + +@Service +public class DictService { + + @Resource + private DictDao dictDao; + + @Resource + private DictDataDao dictDataDao; + + @Resource + private CacheManager cacheManager; + + @Resource + private DictManager dictManager; + + /** + * 获取全部数据 + */ + public List getAll() { + return dictDataDao.getAll(); + } + + /** + * 获取所有字典 + */ + public List getAllDict() { + List dictEntityList = dictDao.selectList(null).stream().filter(e -> !e.getDisabledFlag()).collect(Collectors.toList()); + return SmartBeanUtil.copyList(dictEntityList, DictVO.class); + } + + /** + * 分页查询 + */ + public PageResult queryPage(DictQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = dictDao.queryPage(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + */ + public synchronized ResponseDTO add(DictAddForm addForm) { + DictEntity existDictCode = dictDao.selectByCode(addForm.getDictCode()); + if (null != existDictCode) { + return ResponseDTO.userErrorParam("数据字典编码已经存在!"); + } + + DictEntity dictEntity = SmartBeanUtil.copy(addForm, DictEntity.class); + dictDao.insert(dictEntity); + return ResponseDTO.ok(); + } + + /** + * 禁用 启用 + */ + public ResponseDTO updateDisabled(Long dictId) { + DictEntity dictEntity = dictDao.selectById(dictId); + if (dictEntity == null) { + return ResponseDTO.userErrorParam("数据不存在"); + } + + dictEntity.setDisabledFlag(!dictEntity.getDisabledFlag()); + dictDao.updateById(dictEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + */ + @CacheEvict(CacheKeyConst.Dict.DICT_DATA) + public synchronized ResponseDTO update(DictUpdateForm updateForm) { + DictEntity existDictCode = dictDao.selectByCode(updateForm.getDictCode()); + if (null != existDictCode && !existDictCode.getDictId().equals(updateForm.getDictId())) { + return ResponseDTO.userErrorParam("数据字典编码已经存在!"); + } + + DictEntity dictEntity = SmartBeanUtil.copy(updateForm, DictEntity.class); + dictDao.updateById(dictEntity); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + */ + @CacheEvict(CacheKeyConst.Dict.DICT_DATA) + public synchronized ResponseDTO batchDelete(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return ResponseDTO.ok(); + } + + dictDao.deleteBatchIds(idList); + return ResponseDTO.ok(); + } + + /** + * 单个删除 + */ + @CacheEvict(CacheKeyConst.Dict.DICT_DATA) + public synchronized ResponseDTO delete(Long dictId) { + if (null == dictId) { + return ResponseDTO.ok(); + } + + dictDao.deleteById(dictId); + return ResponseDTO.ok(); + } + + + // -------------- 字典数据 -------------------- + + /** + * 分页查询 + */ + public List queryDictData(Long dictId) { + return dictDataDao.queryByDictId(dictId); + } + + /** + * 获取字典 + */ + + public DictDataVO getDictData(String dictCode, String dataValue) { + return dictManager.getDictData(dictCode, dataValue); + } + + /** + * 获取字典Label + */ + public String getDictDataLabel(String dictCode, String dataValue) { + DictDataVO dictData = getDictData(dictCode, dataValue); + return dictData == null ? "" : dictData.getDataLabel(); + } + + /** + * 添加 + */ + public synchronized ResponseDTO addDictData(DictDataAddForm addForm) { + + addForm.setDataValue(SmartStringUtil.trim(addForm.getDataValue())); + + DictEntity dictEntity = dictDao.selectById(addForm.getDictId()); + if (null == dictEntity) { + return ResponseDTO.userErrorParam("数据字典不存在"); + } + + DictDataEntity existData = dictDataDao.selectByDictIdAndValue(addForm.getDictId(), addForm.getDataValue()); + if (null != existData) { + return ResponseDTO.userErrorParam("已存在相同value的数据"); + } + + DictDataEntity dictDataEntity = SmartBeanUtil.copy(addForm, DictDataEntity.class); + dictDataDao.insert(dictDataEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + */ + @CacheEvict(value = CacheKeyConst.Dict.DICT_DATA, key = "#updateForm.dictCode + '_' + #updateForm.dataValue") + public synchronized ResponseDTO updateDictData(DictDataUpdateForm updateForm) { + + updateForm.setDataValue(SmartStringUtil.trim(updateForm.getDataValue())); + + DictEntity dictEntity = dictDao.selectById(updateForm.getDictId()); + if (null == dictEntity) { + return ResponseDTO.userErrorParam("数据字典不存在"); + } + + DictDataEntity existData = dictDataDao.selectByDictIdAndValue(updateForm.getDictId(), updateForm.getDataValue()); + if (null != existData && !existData.getDictDataId().equals(updateForm.getDictDataId())) { + return ResponseDTO.userErrorParam("已存在相同value的数据"); + } + + DictDataEntity dictDataEntity = SmartBeanUtil.copy(updateForm, DictDataEntity.class); + dictDataDao.updateById(dictDataEntity); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + */ + public synchronized ResponseDTO batchDeleteDictData(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return ResponseDTO.ok(); + } + // 清除缓存 + clearDictDataCache(idList); + // 删除 + dictDataDao.deleteBatchIds(idList); + return ResponseDTO.ok(); + } + + /** + * 单个删除 + */ + public synchronized ResponseDTO deleteDictData(Long dictDataId) { + if (null == dictDataId) { + return ResponseDTO.ok(); + } + // 清除缓存 + clearDictDataCache(Collections.singletonList(dictDataId)); + // 删除 + dictDataDao.deleteById(dictDataId); + return ResponseDTO.ok(); + } + + + /** + * 清空字典数据缓存 + */ + private void clearDictDataCache(List idList) { + List dictDataList = dictDataDao.selectByDictDataIds(idList); + Cache cache = cacheManager.getCache(CacheKeyConst.Dict.DICT_DATA); + if (cache == null) { + return; + } + + for (DictDataVO dictDataVO : dictDataList) { + cache.evict(dictDataVO.getDictCode() + "_" + dictDataVO.getDataValue()); + } + } + + + /** + * 更新启用/禁用 + */ + public synchronized ResponseDTO updateDictDataDisabled(Long dictDataId) { + DictDataEntity dictDataEntity = dictDataDao.selectById(dictDataId); + if (dictDataEntity == null) { + return ResponseDTO.userErrorParam("数据不存在"); + } + + dictDataEntity.setDisabledFlag(!dictDataEntity.getDisabledFlag()); + dictDataDao.updateById(dictDataEntity); + return ResponseDTO.ok(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/controller/FeedbackController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/controller/FeedbackController.java new file mode 100644 index 0000000..1d2ffef --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/controller/FeedbackController.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.feedback.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackAddForm; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackQueryForm; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackVO; +import net.lab1024.sa.base.module.support.feedback.service.FeedbackService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 意见反馈 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Tag(name = SwaggerTagConst.Support.FEEDBACK) +@RestController +public class FeedbackController extends SupportBaseController { + + @Resource + private FeedbackService feedbackService; + + @Operation(summary = "意见反馈-分页查询 @author 开云") + @PostMapping("/feedback/query") + public ResponseDTO> query(@RequestBody @Valid FeedbackQueryForm queryForm) { + return feedbackService.query(queryForm); + } + + @Operation(summary = "意见反馈-新增 @author 开云") + @PostMapping("/feedback/add") + public ResponseDTO add(@RequestBody @Valid FeedbackAddForm addForm) { + RequestUser employee = SmartRequestUtil.getRequestUser(); + return feedbackService.add(addForm, employee); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/dao/FeedbackDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/dao/FeedbackDao.java new file mode 100644 index 0000000..034a8af --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/dao/FeedbackDao.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.module.support.feedback.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackEntity; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackQueryForm; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 意见反馈 dao + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface FeedbackDao extends BaseMapper { + + /** + * 分页查询 + */ + List queryPage(Page page, @Param("query") FeedbackQueryForm query); +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackAddForm.java new file mode 100644 index 0000000..9c969f4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackAddForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.base.module.support.feedback.domain; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; + +import javax.validation.constraints.NotBlank; + +/** + * 意见反馈 添加表单 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FeedbackAddForm { + + @Schema(description = "反馈内容") + @NotBlank(message = "反馈内容不能为空") + private String feedbackContent; + + @Schema(description = "反馈图片") + @JsonSerialize(using = FileKeyVoSerializer.class) + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String feedbackAttachment; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackEntity.java new file mode 100644 index 0000000..85d7b4c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackEntity.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.base.module.support.feedback.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 意见反馈 表 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_feedback") +public class FeedbackEntity { + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long feedbackId; + + /** + * 反馈内容 + */ + private String feedbackContent; + + /** + * 反馈附件 + */ + private String feedbackAttachment; + + /** + * 创建人id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 创建人姓名 + */ + private String userName; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackQueryForm.java new file mode 100644 index 0000000..2bda147 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackQueryForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.feedback.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * 意见反馈 查询 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FeedbackQueryForm extends PageParam { + + @Schema(description = "搜索词") + @Length(max = 25, message = "搜索词最多25字符") + private String searchWord; + + @Schema(description = "开始时间", example = "2021-02-14") + private LocalDate startDate; + + @Schema(description = "截止时间", example = "2022-10-15") + private LocalDate endDate; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackVO.java new file mode 100644 index 0000000..5cba8ec --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/domain/FeedbackVO.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.base.module.support.feedback.domain; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.time.LocalDateTime; + +/** + * 意见反馈 返回对象 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FeedbackVO { + + @Schema(description = "主键") + private Long feedbackId; + + @Schema(description = "反馈内容") + private String feedbackContent; + + @Schema(description = "反馈图片") + @JsonSerialize(using = FileKeyVoSerializer.class) + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String feedbackAttachment; + + @Schema(description = "创建人id") + private Long userId; + + @Schema(description = "创建人姓名") + private String userName; + + @SchemaEnum(value = UserTypeEnum.class, desc = "创建人类型") + private Integer userType; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "创建时间") + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/service/FeedbackService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/service/FeedbackService.java new file mode 100644 index 0000000..cbe6100 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/feedback/service/FeedbackService.java @@ -0,0 +1,60 @@ +package net.lab1024.sa.base.module.support.feedback.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.feedback.dao.FeedbackDao; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackAddForm; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackEntity; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackQueryForm; +import net.lab1024.sa.base.module.support.feedback.domain.FeedbackVO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + + +/** + * 意见反馈 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class FeedbackService { + + @Resource + private FeedbackDao feedbackDao; + + /** + * 分页查询 + * + */ + public ResponseDTO> query(FeedbackQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = feedbackDao.queryPage(page, queryForm); + PageResult pageResultDTO = SmartPageUtil.convert2PageResult(page, list); + if (pageResultDTO.getEmptyFlag()) { + return ResponseDTO.ok(pageResultDTO); + } + return ResponseDTO.ok(pageResultDTO); + } + + /** + * 新建 + */ + public ResponseDTO add(FeedbackAddForm addForm, RequestUser requestUser) { + FeedbackEntity feedback = SmartBeanUtil.copy(addForm, FeedbackEntity.class); + feedback.setUserType(requestUser.getUserType().getValue()); + feedback.setUserId(requestUser.getUserId()); + feedback.setUserName(requestUser.getUserName()); + feedbackDao.insert(feedback); + return ResponseDTO.ok(); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/constant/FileFolderTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/constant/FileFolderTypeEnum.java new file mode 100644 index 0000000..a56617b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/constant/FileFolderTypeEnum.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.base.module.support.file.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 文件服务 文件夹位置类型枚举类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum FileFolderTypeEnum implements BaseEnum { + + /** + * 通用 + */ + COMMON(1, FileFolderTypeEnum.FOLDER_PUBLIC + "/common/", "通用"), + + /** + * 公告 + */ + NOTICE(2, FileFolderTypeEnum.FOLDER_PUBLIC + "/notice/", "公告"), + + /** + * 帮助中心 + */ + HELP_DOC(3, FileFolderTypeEnum.FOLDER_PUBLIC + "/help-doc/", "帮助中心"), + + /** + * 意见反馈 + */ + FEEDBACK(4, FileFolderTypeEnum.FOLDER_PUBLIC + "/feedback/", "意见反馈"), + + ; + + /** + * 公用读取文件夹 public + */ + public static final String FOLDER_PUBLIC = "public"; + + /** + * 私有读取文件夹 private, 私有文件夹会设置 只读权限,并且 文件url 拥有过期时间 + */ + public static final String FOLDER_PRIVATE = "private"; + + private final Integer value; + + private final String folder; + + private final String desc; +} + diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/controller/FileController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/controller/FileController.java new file mode 100644 index 0000000..36d4fd2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/controller/FileController.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.base.module.support.file.controller; + +import cn.hutool.extra.servlet.ServletUtil; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.constant.RequestHeaderConst; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.common.util.SmartResponseUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.base.module.support.file.service.FileService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.FILE) +public class FileController extends SupportBaseController { + + @Resource + private FileService fileService; + + + @Operation(summary = "文件上传 @author 胡克") + @PostMapping("/file/upload") + public ResponseDTO upload(@RequestParam MultipartFile file, @RequestParam Integer folder) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + return fileService.fileUpload(file, folder, requestUser); + } + + @Operation(summary = "获取文件URL:根据fileKey @author 胡克") + @GetMapping("/file/getFileUrl") + public ResponseDTO getUrl(@RequestParam String fileKey) { + return fileService.getFileUrl(fileKey); + } + + @Operation(summary = "下载文件流(根据fileKey) @author 胡克") + @GetMapping("/file/downLoad") + public void downLoad(@RequestParam String fileKey, HttpServletRequest request, HttpServletResponse response) throws IOException { + String userAgent = ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT); + ResponseDTO downloadFileResult = fileService.getDownloadFile(fileKey, userAgent); + if (!downloadFileResult.getOk()) { + SmartResponseUtil.write(response, downloadFileResult); + return; + } + // 下载文件信息 + FileDownloadVO fileDownloadVO = downloadFileResult.getData(); + // 设置下载消息头 + SmartResponseUtil.setDownloadFileHeader(response, fileDownloadVO.getMetadata().getFileName(), fileDownloadVO.getMetadata().getFileSize()); + // 下载 + response.getOutputStream().write(fileDownloadVO.getData()); + } + + //根据attachmentIds获取文件列表 + @Operation(summary = "根据attachmentIds获取文件列表 @author 胡克") + @GetMapping("/file/getFileList") + public ResponseDTO> getFileList(@RequestParam String fileIds) { + String[] fileKeyArray = fileIds.split(","); + List fileKeyList = Arrays.asList(fileKeyArray); + List fileListById = fileService.getFileListById(fileKeyList); + return ResponseDTO.ok(fileListById); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/dao/FileDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/dao/FileDao.java new file mode 100644 index 0000000..024f2d5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/dao/FileDao.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.base.module.support.file.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.base.module.support.file.domain.entity.FileEntity; +import net.lab1024.sa.base.module.support.file.domain.form.FileQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface FileDao extends BaseMapper { + + /** + * 文件key单个查询 + * + * @param fileKey + * @return + */ + FileVO getByFileKey(@Param("fileKey") String fileKey); + + + /** + * 批量获取 + */ + List selectByFileKeyList(@Param("fileKeyList") Collection fileKeyList); + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") FileQueryForm queryForm); + + List selectByFileId(@Param("fileKeyList") List fileKeyList); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/entity/FileEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/entity/FileEntity.java new file mode 100644 index 0000000..2fdb341 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/entity/FileEntity.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.base.module.support.file.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName(value = "t_file") +public class FileEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long fileId; + + /** + * 文件夹类型 + */ + private Integer folderType; + + /** + * 文件名称 + */ + private String fileName; + + /** + * 文件大小 + */ + private Long fileSize; + + /** + * 文件key,用于文件下载 + */ + private String fileKey; + + /** + * 文件类型 + */ + private String fileType; + + /** + * 创建人,即上传人 + */ + private Long creatorId; + + /** + * 用户类型 + */ + private Integer creatorUserType; + + /** + * 创建人 姓名 + */ + private String creatorName; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} + diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/form/FileQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/form/FileQueryForm.java new file mode 100644 index 0000000..84d7a00 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/form/FileQueryForm.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.module.support.file.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.file.constant.FileFolderTypeEnum; + +import java.time.LocalDate; + +/** + * 文件信息查询 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FileQueryForm extends PageParam { + + @SchemaEnum(value = FileFolderTypeEnum.class, desc = "文件夹类型") + @CheckEnum(value = FileFolderTypeEnum.class, message = "文件夹类型 错误") + private Integer folderType; + + @Schema(description = "文件名词") + private String fileName; + + @Schema(description = "文件Key") + private String fileKey; + + @Schema(description = "文件类型") + private String fileType; + + @Schema(description = "创建人") + private String creatorName; + + @Schema(description = "创建时间") + private LocalDate createTimeBegin; + + @Schema(description = "创建时间") + private LocalDate createTimeEnd; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/form/FileUrlUploadForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/form/FileUrlUploadForm.java new file mode 100644 index 0000000..f269ba6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/form/FileUrlUploadForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.file.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.file.constant.FileFolderTypeEnum; + +import javax.validation.constraints.NotBlank; + +/** + * url上传文件 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FileUrlUploadForm { + + @SchemaEnum(value = FileFolderTypeEnum.class, desc = "业务类型") + @CheckEnum(value = FileFolderTypeEnum.class, required = true, message = "业务类型错误") + private Integer folder; + + @Schema(description = "文件url") + @NotBlank(message = "文件url不能为空") + private String fileUrl; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileDownloadVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileDownloadVO.java new file mode 100644 index 0000000..fd2756f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileDownloadVO.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.file.domain.vo; + +import lombok.Data; + +/** + * 文件下载 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FileDownloadVO { + + /** + * 文件字节数据 + */ + private byte[] data; + + /** + * 文件元数据 + */ + private FileMetadataVO metadata; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileMetadataVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileMetadataVO.java new file mode 100644 index 0000000..51b497f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileMetadataVO.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.file.domain.vo; + +import lombok.Data; + +/** + * 文件元数据 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FileMetadataVO { + + /** + * 文件名称 + */ + private String fileName; + + /** + * 文件大小/字节 + */ + private Long fileSize; + + /** + * 文件格式 + */ + private String fileFormat; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileUploadVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileUploadVO.java new file mode 100644 index 0000000..11772f5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileUploadVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.base.module.support.file.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 文件信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FileUploadVO { + + @Schema(description = "文件id") + private Long fileId; + + @Schema(description = "文件名称") + private String fileName; + + @Schema(description = "fileUrl") + private String fileUrl; + + @Schema(description = "fileKey") + private String fileKey; + + @Schema(description = "文件大小") + private Long fileSize; + + @Schema(description = "文件类型") + private String fileType; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileVO.java new file mode 100644 index 0000000..e4fd696 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/domain/vo/FileVO.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.base.module.support.file.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.file.constant.FileFolderTypeEnum; + +import java.time.LocalDateTime; + +/** + * 文件信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class FileVO { + + @Schema(description = "主键") + private Long fileId; + + @Schema(description = "存储文件夹类型") + @SchemaEnum(FileFolderTypeEnum.class) + private Integer folderType; + + @Schema(description = "文件名称") + private String fileName; + + @Schema(description = "文件大小") + private Integer fileSize; + + @Schema(description = "文件类型") + private String fileType; + + @Schema(description = "文件路径") + private String fileKey; + + @Schema(description = "上传人") + private Long creatorId; + + @Schema(description = "上传人") + private String creatorName; + + @SchemaEnum(value = UserTypeEnum.class, desc = "创建人类型") + private Integer creatorUserType; + + @Schema(description = "文件展示url") + private String fileUrl; + + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileService.java new file mode 100644 index 0000000..83c9592 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileService.java @@ -0,0 +1,241 @@ +package net.lab1024.sa.base.module.support.file.service; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.file.constant.FileFolderTypeEnum; +import net.lab1024.sa.base.module.support.file.dao.FileDao; +import net.lab1024.sa.base.module.support.file.domain.entity.FileEntity; +import net.lab1024.sa.base.module.support.file.domain.form.FileQueryForm; +import net.lab1024.sa.base.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.base.module.support.securityprotect.service.SecurityFileService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class FileService { + + /** + * 文件名最大长度 + */ + private static final int FILE_NAME_MAX_LENGTH = 100; + + @Resource + private IFileStorageService fileStorageService; + + @Resource + private FileDao fileDao; + + @Resource + private SecurityFileService securityFileService; + + /** + * 文件上传服务 + * + * @param file + * @param folderType 文件夹类型 + * @return + */ + public ResponseDTO fileUpload(MultipartFile file, Integer folderType, RequestUser requestUser) { + FileFolderTypeEnum folderTypeEnum = SmartEnumUtil.getEnumByValue(folderType, FileFolderTypeEnum.class); + if (null == folderTypeEnum) { + return ResponseDTO.userErrorParam("文件夹错误"); + } + + if (null == file || file.getSize() == 0) { + return ResponseDTO.userErrorParam("上传文件不能为空"); + } + + // 校验文件名称 + String originalFilename = file.getOriginalFilename(); + if (StringUtils.isBlank(originalFilename)) { + return ResponseDTO.userErrorParam("上传文件名称不能为空"); + } + + if (originalFilename.length() > FILE_NAME_MAX_LENGTH) { + return ResponseDTO.userErrorParam("文件名称最大长度为:" + FILE_NAME_MAX_LENGTH); + } + + // 校验文件大小以及安全性 + ResponseDTO validateFile = securityFileService.checkFile(file); + if (!validateFile.getOk()) { + return ResponseDTO.error(validateFile); + } + + // 进行上传 + ResponseDTO response = fileStorageService.upload(file, folderTypeEnum.getFolder()); + if (!response.getOk()) { + return response; + } + + // 上传成功 保存记录数据库 + FileUploadVO uploadVO = response.getData(); + FileEntity fileEntity = new FileEntity(); + fileEntity.setFolderType(folderTypeEnum.getValue()); + fileEntity.setFileName(originalFilename); + fileEntity.setFileSize(file.getSize()); + fileEntity.setFileKey(uploadVO.getFileKey()); + fileEntity.setFileType(uploadVO.getFileType()); + fileEntity.setCreatorId(requestUser == null ? null : requestUser.getUserId()); + fileEntity.setCreatorName(requestUser == null ? null : requestUser.getUserName()); + fileEntity.setCreatorUserType(requestUser == null ? null : requestUser.getUserType().getValue()); + fileDao.insert(fileEntity); + + // 将fileId 返回给前端 + uploadVO.setFileId(fileEntity.getFileId()); + uploadVO.setFileName(originalFilename); + return response; + } + + /** + * 批量获取文件信息 + * + * @param fileKeyList + * @return + */ + public List getFileList(List fileKeyList) { + if (CollectionUtils.isEmpty(fileKeyList)) { + return Lists.newArrayList(); + } + List fileVOS = fileDao.selectByFileId(fileKeyList); + fileVOS.stream().forEach(fileVO -> { + fileVO.setFileUrl(fileVO.getFileKey()); + }); + // 查询数据库,并获取 file url + HashSet fileKeySet = new HashSet<>(fileKeyList); + Map fileMap = fileDao.selectByFileKeyList(fileKeySet) + .stream().collect(Collectors.toMap(FileVO::getFileKey, Function.identity())); + + for (FileVO fileVO : fileMap.values()) { + ResponseDTO fileUrlResponse = fileStorageService.getFileUrl(fileVO.getFileKey()); + if (fileUrlResponse.getOk()) { + fileVO.setFileUrl(fileUrlResponse.getData()); + } + } + + // 返回结果 + List result = Lists.newArrayListWithCapacity(fileKeyList.size()); + for (String fileKey : fileKeyList) { + FileVO fileVO = fileMap.get(fileKey); + if (fileVO != null) { + result.add(fileVO); + } + } + + return result; + } + + public List getFileListById(List fileIdList) { + if (CollectionUtils.isEmpty(fileIdList)) { + return Lists.newArrayList(); + } + List fileKeyList = new ArrayList<>(); + List fileVOS = fileDao.selectByFileId(fileIdList); + fileVOS.stream().forEach(fileVO -> { + fileKeyList.add(fileVO.getFileKey()); + }); + // 查询数据库,并获取 file url + HashSet fileKeySet = new HashSet<>(fileKeyList); + Map fileMap = fileDao.selectByFileKeyList(fileKeySet) + .stream().collect(Collectors.toMap(FileVO::getFileKey, Function.identity())); + + for (FileVO fileVO : fileMap.values()) { + ResponseDTO fileUrlResponse = fileStorageService.getFileUrl(fileVO.getFileKey()); + if (fileUrlResponse.getOk()) { + fileVO.setFileUrl(fileUrlResponse.getData()); + } + } + + // 返回结果 + List result = Lists.newArrayListWithCapacity(fileKeyList.size()); + for (String fileKey : fileKeyList) { + FileVO fileVO = fileMap.get(fileKey); + if (fileVO != null) { + result.add(fileVO); + } + } + + return result; + } + + /** + * 根据文件绝对路径 获取文件URL + * 支持单个 key 逗号分隔的形式 + * + * @param fileKeys + * @return + */ + public ResponseDTO getFileUrl(String fileKeys) { + if (StringUtils.isBlank(fileKeys)) { + return ResponseDTO.error(UserErrorCode.PARAM_ERROR); + } + + List fileKeyArray = StrUtil.split(fileKeys, StringConst.SEPARATOR); + List fileUrlList = Lists.newArrayListWithCapacity(fileKeyArray.size()); + for (String fileKey : fileKeyArray) { + ResponseDTO fileUrlResponse = fileStorageService.getFileUrl(fileKey); + if (fileUrlResponse.getOk()) { + fileUrlList.add(fileUrlResponse.getData()); + } + } + return ResponseDTO.ok(SmartStringUtil.join(StringConst.SEPARATOR, fileUrlList)); + } + + + /** + * 根据文件服务类型 和 FileKey 下载文件 + */ + public ResponseDTO getDownloadFile(String fileKey, String userAgent) { + FileVO fileVO = fileDao.getByFileKey(fileKey); + if (fileVO == null) { + return ResponseDTO.userErrorParam("文件不存在"); + } + + // 根据文件服务类 获取对应文件服务 查询 url + ResponseDTO download = fileStorageService.download(fileKey); + if (download.getOk()) { + download.getData().getMetadata().setFileName(fileVO.getFileName()); + } + return download; + } + + /** + * 分页查询 + */ + public PageResult queryPage(FileQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = fileDao.queryPage(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileStorageCloudServiceImpl.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileStorageCloudServiceImpl.java new file mode 100644 index 0000000..99849a9 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileStorageCloudServiceImpl.java @@ -0,0 +1,249 @@ +package net.lab1024.sa.base.module.support.file.service; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.IdUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.code.SystemErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.config.FileConfig; +import net.lab1024.sa.base.constant.RedisKeyConst; +import net.lab1024.sa.base.module.support.file.constant.FileFolderTypeEnum; +import net.lab1024.sa.base.module.support.file.dao.FileDao; +import net.lab1024.sa.base.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileMetadataVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.base.module.support.redis.RedisService; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import software.amazon.awssdk.core.ResponseBytes; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.core.sync.ResponseTransformer; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.*; +import software.amazon.awssdk.services.s3.presigner.S3Presigner; +import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; +import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; + +import javax.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + * 云计算 实现 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class FileStorageCloudServiceImpl implements IFileStorageService { + + /** + * 自定义元数据 文件名称 + */ + private static final String USER_METADATA_FILE_NAME = "file-name"; + + /** + * 自定义元数据 文件格式 + */ + private static final String USER_METADATA_FILE_FORMAT = "file-format"; + + /** + * 自定义元数据 文件大小 + */ + private static final String USER_METADATA_FILE_SIZE = "file-size"; + + @Resource + private S3Client s3Client; + + @Resource + private FileConfig cloudConfig; + + @Resource + private RedisService redisService; + + @Resource + private FileDao fileDao; + + @Override + public ResponseDTO upload(MultipartFile file, String path) { + // 设置文件 key + String originalFileName = file.getOriginalFilename(); + if (SmartStringUtil.isEmpty(originalFileName)) { + return ResponseDTO.userErrorParam("上传文件名为空"); + } + + String fileType = FilenameUtils.getExtension(originalFileName); + String uuid = IdUtil.fastSimpleUUID(); + String time = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_FORMATTER); + String fileKey = path + uuid + "_" + time + "." + fileType; + + // 文件名称 URL 编码 + String urlEncoderFilename; + try { + urlEncoderFilename = URLEncoder.encode(originalFileName, "utf-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + Map userMetadata = new HashMap<>(10); + userMetadata.put(USER_METADATA_FILE_NAME, urlEncoderFilename); + userMetadata.put(USER_METADATA_FILE_FORMAT, fileType); + userMetadata.put(USER_METADATA_FILE_SIZE, String.valueOf(file.getSize())); + + // 根据文件路径获取并设置访问权限 + ObjectCannedACL acl = this.getACL(path); + PutObjectRequest putObjectRequest = PutObjectRequest.builder() + .bucket(cloudConfig.getBucketName()) + .key(fileKey) + .metadata(userMetadata) + .contentLength(file.getSize()) + .contentType(this.getContentType(fileType)) + .contentEncoding(StandardCharsets.UTF_8.name()) + .contentDisposition("attachment;filename=" + urlEncoderFilename) + .acl(acl) + .build(); + InputStream inputStream = null; + try { + inputStream = file.getInputStream(); + s3Client.putObject(putObjectRequest, RequestBody.fromInputStream(inputStream, file.getSize())); + } catch (IOException e) { + log.error("文件上传-发生异常:", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "上传失败"); + } finally { + IOUtils.closeQuietly(inputStream); + } + // 返回上传结果 + FileUploadVO uploadVO = new FileUploadVO(); + uploadVO.setFileName(originalFileName); + uploadVO.setFileType(fileType); + // 根据 访问权限 返回不同的 URL + String url = cloudConfig.getUrlPrefix() + fileKey; + if (ObjectCannedACL.PRIVATE.equals(acl)) { + // 获取临时访问的URL + url = this.getFileUrl(fileKey).getData(); + } + uploadVO.setFileUrl(url); + uploadVO.setFileKey(fileKey); + uploadVO.setFileSize(file.getSize()); + return ResponseDTO.ok(uploadVO); + } + + /** + * 获取文件url + * + * @param fileKey 文件key + * @return url + */ + @Override + public ResponseDTO getFileUrl(String fileKey) { + if (StringUtils.isBlank(fileKey)) { + return ResponseDTO.userErrorParam("文件不存在,key为空"); + } + + if (!fileKey.startsWith(FileFolderTypeEnum.FOLDER_PRIVATE)) { + // 不是私有的 都公共读 + return ResponseDTO.ok(cloudConfig.getUrlPrefix() + fileKey); + } + + // 如果是私有的,则规定时间内可以访问,超过规定时间,则连接失效 + + String fileRedisKey = RedisKeyConst.Support.FILE_PRIVATE_VO + fileKey; + FileVO fileVO = redisService.getObject(fileRedisKey, FileVO.class); + if (fileVO == null) { + fileVO = fileDao.getByFileKey(fileKey); + if (fileVO == null) { + return ResponseDTO.userErrorParam("文件不存在"); + } + GetObjectRequest getUrlRequest = GetObjectRequest.builder().bucket(cloudConfig.getBucketName()).key(fileKey).build(); + GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder().signatureDuration(Duration.ofSeconds(cloudConfig.getPrivateUrlExpireSeconds())).getObjectRequest(getUrlRequest).build(); + + S3Presigner presigner = S3Presigner.builder().region(Region.of(cloudConfig.getRegion())).build(); + + PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest); + String url = presignedGetObjectRequest.url().toString(); + fileVO.setFileUrl(url); + redisService.set(fileRedisKey, fileVO, cloudConfig.getPrivateUrlExpireSeconds() - 5); + } + + return ResponseDTO.ok(fileVO.getFileUrl()); + } + + + /** + * 流式下载(名称为原文件) + */ + @Override + public ResponseDTO download(String key) { + + // 获取文件 meta + HeadObjectRequest objectRequest = HeadObjectRequest.builder().bucket(this.cloudConfig.getBucketName()).key(key).build(); + HeadObjectResponse headObjectResponse = s3Client.headObject(objectRequest); + Map userMetadata = headObjectResponse.metadata(); + FileMetadataVO metadataDTO = null; + if (MapUtils.isNotEmpty(userMetadata)) { + metadataDTO = new FileMetadataVO(); + metadataDTO.setFileFormat(userMetadata.get(USER_METADATA_FILE_FORMAT)); + metadataDTO.setFileName(userMetadata.get(USER_METADATA_FILE_NAME)); + String fileSizeStr = userMetadata.get(USER_METADATA_FILE_SIZE); + Long fileSize = StringUtils.isBlank(fileSizeStr) ? null : Long.valueOf(fileSizeStr); + metadataDTO.setFileSize(fileSize); + } + + //获取oss对象 + GetObjectRequest getObjectRequest = GetObjectRequest.builder().bucket(cloudConfig.getBucketName()).key(key).build(); + ResponseBytes s3ClientObject = s3Client.getObject(getObjectRequest, ResponseTransformer.toBytes()); + + // 输入流转换为字节流 + byte[] buffer = s3ClientObject.asByteArray(); + FileDownloadVO fileDownloadVO = new FileDownloadVO(); + fileDownloadVO.setData(buffer); + fileDownloadVO.setMetadata(metadataDTO); + return ResponseDTO.ok(fileDownloadVO); + } + + /** + * 根据文件夹路径 返回对应的访问权限 + * + * @param fileKey 文件key + * @return 权限 + */ + private ObjectCannedACL getACL(String fileKey) { + // 公用读 + if (fileKey.contains(FileFolderTypeEnum.FOLDER_PUBLIC)) { + return ObjectCannedACL.PUBLIC_READ; + } + // 其他默认私有读写 + return ObjectCannedACL.PRIVATE; + } + + /** + * 单个删除文件 + * 根据 file key 删除文件 + * ps:不能删除fileKey不为空的文件夹 + * + * @param fileKey 文件or文件夹 + */ + @Override + public ResponseDTO delete(String fileKey) { + DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder().bucket(cloudConfig.getBucketName()).key(fileKey).build(); + s3Client.deleteObject(deleteObjectRequest); + return ResponseDTO.ok(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileStorageLocalServiceImpl.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileStorageLocalServiceImpl.java new file mode 100644 index 0000000..c75ce0b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/FileStorageLocalServiceImpl.java @@ -0,0 +1,193 @@ +package net.lab1024.sa.base.module.support.file.service; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.net.NetUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.code.SystemErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileMetadataVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileUploadVO; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * 本地存储 实现 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( 1024创新实验室 ) + */ +@Slf4j +public class FileStorageLocalServiceImpl implements IFileStorageService { + + + public static final String UPLOAD_MAPPING = "/upload"; + + @Value("${file.storage.local.upload-path}") + private String uploadPath; + + @Value("${file.storage.local.url-prefix}") + private String urlPrefix; + + @Value("${server.servlet.context-path}") + private String contextPath; + + @Value("${server.port}") + private String port; + + @PostConstruct + public void initUrlPrefix() { + if (SmartStringUtil.isNotEmpty(urlPrefix)) { + return; + } + + String localhostIp = NetUtil.getLocalhostStr(); + String finalContextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath; + if (finalContextPath.endsWith("/")) { + finalContextPath = finalContextPath.substring(0, finalContextPath.length() - 1); + } + urlPrefix = "http://" + localhostIp + ":" + port + finalContextPath + UPLOAD_MAPPING; + urlPrefix = urlPrefix.endsWith("/") ? urlPrefix : urlPrefix + "/"; + } + + @Override + public ResponseDTO upload(MultipartFile multipartFile, String path) { + if (null == multipartFile) { + return ResponseDTO.userErrorParam("上传文件不能为空"); + } + String filePath = uploadPath + path; + File directory = new File(filePath); + if (!directory.exists()) { + // 目录不存在,新建 + directory.mkdirs(); + } + if (!path.endsWith("/")) { + path = path + "/"; + } + FileUploadVO fileUploadVO = new FileUploadVO(); + //原文件名 + String originalFileName = multipartFile.getOriginalFilename(); + //新文件名 + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + String time = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_FORMATTER); + String newFileName = uuid + "_" + time; + String fileType = FilenameUtils.getExtension(originalFileName); + if (SmartStringUtil.isNotEmpty(fileType)) { + newFileName = newFileName + "." + fileType; + } + //生成文件key + String fileKey = path + newFileName; + //创建文件 + File fileTemp = new File(new File(filePath + newFileName).getAbsolutePath()); + try { + multipartFile.transferTo(fileTemp); + fileUploadVO.setFileUrl(this.generateFileUrl(fileKey)); + fileUploadVO.setFileName(newFileName); + fileUploadVO.setFileKey(fileKey); + fileUploadVO.setFileSize(multipartFile.getSize()); + fileUploadVO.setFileType(FilenameUtils.getExtension(originalFileName)); + } catch (IOException e) { + if (fileTemp.exists() && fileTemp.isFile()) { + fileTemp.delete(); + } + log.error("", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "上传失败"); + } + return ResponseDTO.ok(fileUploadVO); + } + + /** + * 生成fileUrl地址 + * + * @param filePath + * @return + */ + public String generateFileUrl(String filePath) { + return urlPrefix + filePath; + } + + /** + * 获取文件Url + * + * @param fileKey + * @return + */ + @Override + public ResponseDTO getFileUrl(String fileKey) { + if (StringUtils.isBlank(fileKey)) { + return ResponseDTO.userErrorParam("文件不存在,key为空"); + } + + String fileUrl = this.generateFileUrl(fileKey); + return ResponseDTO.ok(fileUrl); + } + + /** + * 文件下载 + * + * @param fileKey + * @return + */ + @Override + public ResponseDTO download(String fileKey) { + String filePath = uploadPath + fileKey; + File localFile = new File(filePath); + InputStream in = null; + try { + in = Files.newInputStream(localFile.toPath()); + // 输入流转换为字节流 + byte[] buffer = FileCopyUtils.copyToByteArray(in); + FileDownloadVO fileDownloadVO = new FileDownloadVO(); + fileDownloadVO.setData(buffer); + + FileMetadataVO fileMetadataDTO = new FileMetadataVO(); + fileMetadataDTO.setFileName(localFile.getName()); + fileMetadataDTO.setFileSize(localFile.length()); + fileMetadataDTO.setFileFormat(FilenameUtils.getExtension(localFile.getName())); + fileDownloadVO.setMetadata(fileMetadataDTO); + + return ResponseDTO.ok(fileDownloadVO); + } catch (IOException e) { + log.error("文件下载-发生异常:", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "文件下载失败"); + } finally { + try { + // 关闭输入流 + if (in != null) { + in.close(); + } + } catch (IOException e) { + log.error("文件下载-发生异常:", e); + } + } + } + + @Override + public ResponseDTO delete(String fileKey) { + String filePath = uploadPath + fileKey; + File localFile = new File(filePath); + try { + FileUtils.forceDelete(localFile); + } catch (IOException e) { + log.error("删除本地文件失败:{}", filePath, e); + } + return ResponseDTO.ok(); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/IFileStorageService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/IFileStorageService.java new file mode 100644 index 0000000..aa4ec75 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/file/service/IFileStorageService.java @@ -0,0 +1,99 @@ +package net.lab1024.sa.base.module.support.file.service; + +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.base.module.support.file.domain.vo.FileUploadVO; +import org.springframework.web.multipart.MultipartFile; + +/** + * 接口 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public interface IFileStorageService { + + /** + * 文件上传 + * + * @param file + * @param path + * @return + */ + ResponseDTO upload(MultipartFile file, String path); + + /** + * 获取文件url + * + * @param fileKey + * @return + */ + ResponseDTO getFileUrl(String fileKey); + + + /** + * 流式下载(名称为原文件) + * + * @param key + * @return + */ + ResponseDTO download(String key); + + /** + * 单个删除文件 + * 根据文件key删除 + * + * @param fileKey + * @return + */ + ResponseDTO delete(String fileKey); + + + /** + * 获取文件类型 + * + * @param fileExt + * @return + */ + default String getContentType(String fileExt) { + // 文件的后缀名 + if ("bmp".equalsIgnoreCase(fileExt)) { + return "image/bmp"; + } + if ("gif".equalsIgnoreCase(fileExt)) { + return "image/gif"; + } + if ("jpeg".equalsIgnoreCase(fileExt) || "jpg".equalsIgnoreCase(fileExt)) { + return "image/jpeg"; + } + if ("png".equalsIgnoreCase(fileExt)) { + return "image/png"; + } + if ("html".equalsIgnoreCase(fileExt)) { + return "text/html"; + } + if ("txt".equalsIgnoreCase(fileExt)) { + return "text/plain"; + } + if ("vsd".equalsIgnoreCase(fileExt)) { + return "application/vnd.visio"; + } + if ("ppt".equalsIgnoreCase(fileExt) || "pptx".equalsIgnoreCase(fileExt)) { + return "application/vnd.ms-powerpoint"; + } + if ("doc".equalsIgnoreCase(fileExt) || "docx".equalsIgnoreCase(fileExt)) { + return "application/msword"; + } + if ("pdf".equalsIgnoreCase(fileExt)) { + return "application/pdf"; + } + if ("xml".equalsIgnoreCase(fileExt)) { + return "text/xml"; + } + return ""; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordDao.java new file mode 100644 index 0000000..df1ab21 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordDao.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.module.support.heartbeat; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordEntity; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordQueryForm; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface HeartBeatRecordDao extends BaseMapper { + + /** + * 更新心跳日志 + * + * @param id + * @param heartBeatTime + */ + void updateHeartBeatTimeById(@Param("id") Long id, @Param("heartBeatTime") LocalDateTime heartBeatTime); + + /** + * 查询心跳日志 + * + * @param heartBeatRecordEntity + * @return + */ + HeartBeatRecordEntity query(HeartBeatRecordEntity heartBeatRecordEntity); + + /** + * 分页查询 + * @param heartBeatRecordQueryForm + * @return + */ + List pageQuery(Page page, @Param("query") HeartBeatRecordQueryForm heartBeatRecordQueryForm); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordHandler.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordHandler.java new file mode 100644 index 0000000..279a62f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordHandler.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.module.support.heartbeat; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.module.support.heartbeat.core.HeartBeatRecord; +import net.lab1024.sa.base.module.support.heartbeat.core.IHeartBeatRecordHandler; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordEntity; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class HeartBeatRecordHandler implements IHeartBeatRecordHandler { + + @Resource + private HeartBeatRecordDao heartBeatRecordDao; + + /** + * 心跳日志处理方法 + * @param heartBeatRecord + */ + @Override + public void handler(HeartBeatRecord heartBeatRecord) { + HeartBeatRecordEntity heartBeatRecordEntity = SmartBeanUtil.copy(heartBeatRecord, HeartBeatRecordEntity.class); + HeartBeatRecordEntity heartBeatRecordOld = heartBeatRecordDao.query(heartBeatRecordEntity); + if (heartBeatRecordOld == null) { + heartBeatRecordDao.insert(heartBeatRecordEntity); + } else { + heartBeatRecordDao.updateHeartBeatTimeById(heartBeatRecordOld.getHeartBeatRecordId(), heartBeatRecordEntity.getHeartBeatTime()); + } + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatService.java new file mode 100644 index 0000000..e8ffa3e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/HeartBeatService.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.heartbeat; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordQueryForm; +import net.lab1024.sa.base.module.support.heartbeat.domain.HeartBeatRecordVO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class HeartBeatService { + + @Resource + private HeartBeatRecordDao heartBeatRecordDao; + + public ResponseDTO> pageQuery(HeartBeatRecordQueryForm pageParam) { + Page pageQueryInfo = SmartPageUtil.convert2PageQuery(pageParam); + List recordVOList = heartBeatRecordDao.pageQuery(pageQueryInfo,pageParam); + PageResult pageResult = SmartPageUtil.convert2PageResult(pageQueryInfo, recordVOList); + return ResponseDTO.ok(pageResult); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatManager.java new file mode 100644 index 0000000..010d5d5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatManager.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.module.support.heartbeat.core; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 心跳核心调度管理器 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class HeartBeatManager { + + private static final String THREAD_NAME_PREFIX = "smart-heart-beat"; + private static final int THREAD_COUNT = 1; + private static final long INITIAL_DELAY = 60 * 1000L; + + private ScheduledThreadPoolExecutor threadPoolExecutor; + + /** + * 服务状态持久化处理类 + */ + private IHeartBeatRecordHandler heartBeatRecordHandler; + + /** + * 调度配置信息 + */ + private long intervalMilliseconds; + + /** + * @param intervalMilliseconds 间隔执行时间(毫秒) + */ + public HeartBeatManager(Long intervalMilliseconds, + IHeartBeatRecordHandler heartBeatRecordHandler) { + this.intervalMilliseconds = intervalMilliseconds; + this.heartBeatRecordHandler = heartBeatRecordHandler; + //使用守护线程去处理 + this.threadPoolExecutor = new ScheduledThreadPoolExecutor(THREAD_COUNT, r -> { + Thread t = new Thread(r, THREAD_NAME_PREFIX); + if (!t.isDaemon()) { + t.setDaemon(true); + } + return t; + }); + // 开始心跳 + this.beginHeartBeat(); + } + + /** + * 开启心跳 + */ + private void beginHeartBeat() { + HeartBeatRunnable heartBeatRunnable = new HeartBeatRunnable(heartBeatRecordHandler); + threadPoolExecutor.scheduleWithFixedDelay(heartBeatRunnable, INITIAL_DELAY, intervalMilliseconds, TimeUnit.MILLISECONDS); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRecord.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRecord.java new file mode 100644 index 0000000..587f3b4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRecord.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.base.module.support.heartbeat.core; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 心跳记录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HeartBeatRecord { + + /** + * 项目名字 + */ + private String projectPath; + /** + * 服务器ip + */ + private String serverIp; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private LocalDateTime processStartTime; + /** + * 心跳当前时间 + */ + private LocalDateTime heartBeatTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRunnable.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRunnable.java new file mode 100644 index 0000000..65d06ba --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRunnable.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.base.module.support.heartbeat.core; + +import cn.hutool.core.net.NetUtil; +import org.apache.commons.lang3.StringUtils; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; + +/** + * 心跳线程 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class HeartBeatRunnable implements Runnable { + + /** + * 项目路径 + */ + private String projectPath; + /** + * 服务器ip(多网卡) + */ + private List serverIps; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private LocalDateTime processStartTime; + + private IHeartBeatRecordHandler recordHandler; + + public HeartBeatRunnable(IHeartBeatRecordHandler recordHandler) { + this.recordHandler = recordHandler; + this.initServerInfo(); + } + + /** + * 初始化心跳相关信息 + */ + private void initServerInfo(){ + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + this.projectPath = System.getProperty("user.dir"); + this.serverIps = new ArrayList<>(NetUtil.localIpv4s()); + this.processNo = Integer.valueOf(runtimeMXBean.getName().split("@")[0]).intValue(); + this.processStartTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(runtimeMXBean.getStartTime()), ZoneId.systemDefault()); + } + + + @Override + public void run() { + HeartBeatRecord heartBeatRecord = new HeartBeatRecord(); + heartBeatRecord.setProjectPath(this.projectPath); + heartBeatRecord.setServerIp(StringUtils.join(this.serverIps, ";")); + heartBeatRecord.setProcessNo(this.processNo); + heartBeatRecord.setProcessStartTime(this.processStartTime); + heartBeatRecord.setHeartBeatTime(LocalDateTime.now()); + recordHandler.handler(heartBeatRecord); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/IHeartBeatRecordHandler.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/IHeartBeatRecordHandler.java new file mode 100644 index 0000000..d0157d2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/core/IHeartBeatRecordHandler.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.heartbeat.core; + +/** + * 心跳处理接口 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public interface IHeartBeatRecordHandler { + + /** + * 心跳日志处理方法 + * + * @param heartBeatRecord + */ + void handler(HeartBeatRecord heartBeatRecord); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordEntity.java new file mode 100644 index 0000000..ba10db1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordEntity.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.heartbeat.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName(value = "t_heart_beat_record") +public class HeartBeatRecordEntity implements Serializable { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long heartBeatRecordId; + + /** + * 项目名字 + */ + private String projectPath; + /** + * 服务器ip + */ + private String serverIp; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private LocalDateTime processStartTime; + /** + * 心跳当前时间 + */ + private LocalDateTime heartBeatTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java new file mode 100644 index 0000000..873d8cc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.module.support.heartbeat.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 心跳记录 查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HeartBeatRecordQueryForm extends PageParam { + + @Schema(description = "关键字") + private String keywords; + + @Schema(description = "开始日期") + private LocalDate startDate; + + @Schema(description = "结束日期") + private LocalDate endDate; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordVO.java new file mode 100644 index 0000000..10ac931 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordVO.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.module.support.heartbeat.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HeartBeatRecordVO { + + private Integer heartBeatRecordId; + + @Schema(description = "项目路径") + private String projectPath; + + @Schema(description = "服务器ip") + private String serverIp; + + @Schema(description = "进程号") + private Integer processNo; + + @Schema(description = "进程开启时间") + private Date processStartTime; + + @Schema(description = "心跳当前时间") + private Date heartBeatTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/controller/HelpDocController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/controller/HelpDocController.java new file mode 100644 index 0000000..f9482d7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/controller/HelpDocController.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.base.module.support.helpdoc.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocViewRecordQueryForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocCatalogVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocViewRecordVO; +import net.lab1024.sa.base.module.support.helpdoc.service.HelpDocCatalogService; +import net.lab1024.sa.base.module.support.helpdoc.service.HelpDocUserService; +import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Tag(name = SwaggerTagConst.Support.HELP_DOC) +@RestController +public class HelpDocController extends SupportBaseController { + + @Resource + private HelpDocCatalogService helpDocCatalogService; + + @Resource + private HelpDocUserService helpDocUserService; + + // --------------------- 帮助文档 【目录】 ------------------------- + + @Operation(summary = "帮助文档目录-获取全部 @author 卓大") + @GetMapping("/helpDoc/helpDocCatalog/getAll") + public ResponseDTO> getAll() { + return ResponseDTO.ok(helpDocCatalogService.getAll()); + } + + // --------------------- 帮助文档 【用户】------------------------- + + @Operation(summary = "【用户】帮助文档-查看详情 @author 卓大") + @GetMapping("/helpDoc/user/view/{helpDocId}") + @RepeatSubmit + public ResponseDTO view(@PathVariable Long helpDocId, HttpServletRequest request) { + return helpDocUserService.view( + SmartRequestUtil.getRequestUser(), + helpDocId); + } + + @Operation(summary = "【用户】帮助文档-查询全部 @author 卓大") + @GetMapping("/helpDoc/user/queryAllHelpDocList") + @RepeatSubmit + public ResponseDTO> queryAllHelpDocList() { + return helpDocUserService.queryAllHelpDocList(); + } + + + @Operation(summary = "【用户】帮助文档-查询 查看记录 @author 卓大") + @PostMapping("/helpDoc/user/queryViewRecord") + @RepeatSubmit + public ResponseDTO> queryViewRecord(@RequestBody @Valid HelpDocViewRecordQueryForm helpDocViewRecordQueryForm) { + return ResponseDTO.ok(helpDocUserService.queryViewRecord(helpDocViewRecordQueryForm)); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocCatalogDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocCatalogDao.java new file mode 100644 index 0000000..c04ec08 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocCatalogDao.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.helpdoc.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.helpdoc.domain.entity.HelpDocCatalogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 帮助文档目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface HelpDocCatalogDao extends BaseMapper { + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocDao.java new file mode 100644 index 0000000..902f107 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocDao.java @@ -0,0 +1,136 @@ +package net.lab1024.sa.base.module.support.helpdoc.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocQueryForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocRelationForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocViewRecordQueryForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocRelationVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocViewRecordVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 帮助文档 dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface HelpDocDao extends BaseMapper { + + // ================================= 帮助文档【主表 t_help_doc 】 ================================= + + + /** + * 查询 全部相关文档 + * + * @return + */ + List queryAllHelpDocList(); + + /** + * 后管分页查询帮助文档 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") HelpDocQueryForm queryForm); + + + /** + * 更新 阅读量 + * @param helpDocId + * @param userViewCountIncrease + * @param pageViewCountIncrease + */ + void updateViewCount(@Param("helpDocId")Long helpDocId, @Param("userViewCountIncrease")Integer userViewCountIncrease,@Param("pageViewCountIncrease") Integer pageViewCountIncrease); + + + /** + * 根据目录,查询文档 + * + * @param helpDocCatalogId + * @return + */ + List queryHelpDocByCatalogId( @Param("helpDocCatalogId") Long helpDocCatalogId); + + /** + * 根据关联文档id,查询文档 + * + * @param relationId + * @return + */ + List queryHelpDocByRelationId( @Param("relationId") Long relationId); + + // ================================= 关联项目 【子表 t_help_doc_relation 】 ================================= + + /** + * 保存 关联 + * + * @param helpDocId + * @param relationList + */ + void insertRelation(@Param("helpDocId") Long helpDocId, @Param("relationList") List relationList); + + /** + * 删除关联 + * + * @param helpDocId + */ + void deleteRelation(@Param("helpDocId") Long helpDocId); + + /** + * 查询关联 + * + * @param helpDocId + */ + List queryRelationByHelpDoc(@Param("helpDocId") Long helpDocId); + + // ================================= 查看记录【子表 t_help_doc_view_record】 ================================= + + /** + * 查询某个用户的指定文档的阅读量 + * @param helpDocId + * @param userId + * @return + */ + long viewRecordCount(@Param("helpDocId")Long helpDocId, @Param("userId")Long userId); + + /** + * 查询帮助文档的 查看记录 + * @param page + * @param helpDocViewRecordQueryForm + * @return + */ + List queryViewRecordList(Page page, @Param("queryForm") HelpDocViewRecordQueryForm helpDocViewRecordQueryForm); + + /** + * 保存查看记录 + * @param helpDocId + * @param userId + * @param userName + * @param ip + * @param userAgent + */ + void insertViewRecord(@Param("helpDocId") Long helpDocId, @Param("userId") Long userId, @Param("userName") String userName, @Param("ip") String ip, @Param("userAgent") String userAgent,@Param("pageViewCount") Integer pageViewCount); + + /** + * 更新查看记录 + * @param helpDocId + * @param userId + * @param ip + * @param userAgent + */ + void updateViewRecord(@Param("helpDocId")Long helpDocId, @Param("userId")Long userId,@Param("ip") String ip, @Param("userAgent")String userAgent); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java new file mode 100644 index 0000000..bf36ccb --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 帮助文档的 类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_help_doc_catalog") +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HelpDocCatalogEntity { + + @TableId(type = IdType.AUTO) + private Long helpDocCatalogId; + + /** + * 名称 + */ + private String name; + + /** + * 父id + */ + private Long parentId; + + /** + * 排序 + */ + private Integer sort; + + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocEntity.java new file mode 100644 index 0000000..b19542c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocEntity.java @@ -0,0 +1,76 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_help_doc") +public class HelpDocEntity { + + @TableId(type = IdType.AUTO) + private Long helpDocId; + + /** + * 类型 + */ + private Long helpDocCatalogId; + + /** + * 标题 + */ + private String title; + + /** + * 内容 纯文本 + */ + private String contentText; + + /** + * 内容 html + */ + private String contentHtml; + + /** + * 附件 + * 多个英文逗号分隔 + */ + private String attachment; + + /** + * 排序 + */ + private Integer sort; + + /** + * 页面浏览量 + */ + private Integer pageViewCount; + + /** + * 用户浏览量 + */ + private Integer userViewCount; + + /** + * 作者 + */ + private String author; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocAddForm.java new file mode 100644 index 0000000..efa4a1e --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocAddForm.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocAddForm { + + @Schema(description = "标题") + @NotBlank(message = "标题不能为空") + @Length(max = 200, message = "标题最多200字符") + private String title; + + @Schema(description = "分类") + @NotNull(message = "分类不能为空") + private Long helpDocCatalogId; + + @Schema(description = "纯文本内容") + @NotNull(message = "文本内容不能为空") + private String contentText; + + @Schema(description = "html内容") + @NotNull(message = "html内容不能为空") + private String contentHtml; + + @Schema(description = "附件,多个英文逗号分隔|可选") + @Length(max = 1000, message = "最多1000字符") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String attachment; + + @Schema(description = "排序") + @NotNull(message = "排序不能为空") + private Integer sort; + + @Schema(description = "关联的集合") + private List relationList; + + @Schema(description = "作者") + @NotBlank(message = "作者不能为空") + private String author; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java new file mode 100644 index 0000000..a5354a7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 帮助文档 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocCatalogAddForm { + + @Schema(description = "名称") + @NotBlank(message = "名称不能为空") + @Length(max = 200, message = "名称最多200字符") + private String name; + + @Schema(description = "父级") + private Long parentId; + + @Schema(description = "排序") + private Integer sort; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java new file mode 100644 index 0000000..f083ab3 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 帮助文档 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocCatalogUpdateForm extends HelpDocCatalogAddForm { + + @Schema(description = "id") + @NotNull(message = "id") + private Long helpDocCatalogId; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocQueryForm.java new file mode 100644 index 0000000..bee968c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocQueryForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 帮助文档 分页查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocQueryForm extends PageParam { + + @Schema(description = "分类") + private Long helpDocCatalogId; + + @Schema(description = "标题") + private String keywords; + + @Schema(description = "创建-开始时间") + private LocalDate createTimeBegin; + + @Schema(description = "创建-截止时间") + private LocalDate createTimeEnd; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocRelationForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocRelationForm.java new file mode 100644 index 0000000..b36f96c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocRelationForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 帮助文档 关联项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocRelationForm { + + @Schema(description = "关联名称") + @NotBlank(message = "关联名称不能为空") + private String relationName; + + @Schema(description = "关联id") + @NotNull(message = "关联id不能为空") + private Long relationId; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocUpdateForm.java new file mode 100644 index 0000000..1d7fff8 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 更新 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocUpdateForm extends HelpDocAddForm { + + @Schema(description = "id") + @NotNull(message = "通知id不能为空") + private Long helpDocId; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java new file mode 100644 index 0000000..91ab25b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 查阅记录 查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocViewRecordQueryForm extends PageParam { + + @Schema(description = "帮助文档id") + @NotNull(message = "帮助文档id不能为空") + private Long helpDocId; + + @Schema(description = "用户id") + private Long userId; + + @Schema(description = "关键字") + private String keywords; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java new file mode 100644 index 0000000..59d0117 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 帮助文档的 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocCatalogVO { + + @Schema(description = "帮助文档目录id") + private Long helpDocCatalogId; + + @Schema(description = "帮助文档目录-名称") + private String name; + + @Schema(description = "帮助文档目录-父级id") + private Long parentId; + + @Schema(description = "帮助文档目录-排序") + private Integer sort; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocDetailVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocDetailVO.java new file mode 100644 index 0000000..9c1cada --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocDetailVO.java @@ -0,0 +1,65 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 帮助文档 详情 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocDetailVO { + + @Schema(description = "id") + private Long helpDocId; + + @Schema(description = "标题") + private String title; + + @Schema(description = "分类") + private Long helpDocCatalogId; + + @Schema(description = "分类名称") + private Long helpDocCatalogName; + + @Schema(description = "纯文本内容") + private String contentText; + + @Schema(description = "html内容") + private String contentHtml; + + @Schema(description = "附件") + @JsonSerialize(using = FileKeyVoSerializer.class) + private String attachment; + + @Schema(description = "作者") + @NotBlank(message = "作者不能为空") + private String author; + + @Schema(description = "页面浏览量") + private Integer pageViewCount; + + @Schema(description = "用户浏览量") + private Integer userViewCount; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "关联项目") + private List relationList; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRecordVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRecordVO.java new file mode 100644 index 0000000..86b9e97 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRecordVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 - 浏览记录 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocRecordVO { + + @Schema(description = "员工ID") + private Long employeeId; + + @Schema(description = "员工姓名") + private String employeeName; + + @Schema(description = "员工部门名称") + private String departmentName; + + @Schema(description = "查看次数") + private Integer pageViewCount; + + @Schema(description = "首次ip") + private String firstIp; + + @Schema(description = "首次用户设备等标识") + private String firstUserAgent; + + @Schema(description = "首次查看时间") + private LocalDateTime createTime; + + @Schema(description = "最后一次 ip") + private String lastIp; + + @Schema(description = "最后一次 用户设备等标识") + private String lastUserAgent; + + @Schema(description = "最后一次查看时间") + private LocalDateTime updateTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRelationVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRelationVO.java new file mode 100644 index 0000000..4b75391 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRelationVO.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 帮助文档 关联项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocRelationVO { + + @Schema(description = "关联名称") + private String relationName; + + @Schema(description = "关联id") + private Long relationId; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocVO.java new file mode 100644 index 0000000..7917189 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocVO.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocVO { + + @Schema(description = "id") + private Long helpDocId; + + @Schema(description = "标题") + private String title; + + @Schema(description = "分类") + private Long helpDocCatalogId; + + @Schema(description = "分类名称") + private String helpDocCatalogName; + + @Schema(description = "作者") + private String author; + + @Schema(description = "排序") + private Integer sort; + + @Schema(description = "页面浏览量") + private Integer pageViewCount; + + @Schema(description = "用户浏览量") + private Integer userViewCount; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java new file mode 100644 index 0000000..a0b4000 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.module.support.helpdoc.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 - 浏览记录 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class HelpDocViewRecordVO { + + @Schema(description = "ID") + private Long userId; + + @Schema(description = "姓名") + private String userName; + + @Schema(description = "查看次数") + private Integer pageViewCount; + + @Schema(description = "首次ip") + private String firstIp; + + @Schema(description = "首次用户设备等标识") + private String firstUserAgent; + + @Schema(description = "首次查看时间") + private LocalDateTime createTime; + + @Schema(description = "最后一次 ip") + private String lastIp; + + @Schema(description = "最后一次 用户设备等标识") + private String lastUserAgent; + + @Schema(description = "最后一次查看时间") + private LocalDateTime updateTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/manager/HelpDocManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/manager/HelpDocManager.java new file mode 100644 index 0000000..5f253fc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/manager/HelpDocManager.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.base.module.support.helpdoc.manager; + +import net.lab1024.sa.base.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.base.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocRelationForm; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 帮助文档 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class HelpDocManager { + + @Resource + private HelpDocDao helpDocDao; + + /** + * 保存 + * + * @param helpDocEntity + * @param relationList + */ + @Transactional(rollbackFor = Throwable.class) + public void save(HelpDocEntity helpDocEntity, List relationList) { + helpDocDao.insert(helpDocEntity); + Long helpDocId = helpDocEntity.getHelpDocId(); + // 保存关联 + if (CollectionUtils.isNotEmpty(relationList)) { + helpDocDao.insertRelation(helpDocId, relationList); + } + } + + /** + * 更新 + * + * @param helpDocEntity + * @param relationList + */ + @Transactional(rollbackFor = Throwable.class) + public void update(HelpDocEntity helpDocEntity, List relationList) { + helpDocDao.updateById(helpDocEntity); + Long helpDocId = helpDocEntity.getHelpDocId(); + // 保存关联 + if (CollectionUtils.isNotEmpty(relationList)) { + helpDocDao.deleteRelation(helpDocId); + helpDocDao.insertRelation(helpDocId, relationList); + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocCatalogService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocCatalogService.java new file mode 100644 index 0000000..c4a68aa --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocCatalogService.java @@ -0,0 +1,115 @@ +package net.lab1024.sa.base.module.support.helpdoc.service; + +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.module.support.helpdoc.dao.HelpDocCatalogDao; +import net.lab1024.sa.base.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.base.module.support.helpdoc.domain.entity.HelpDocCatalogEntity; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocCatalogAddForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocCatalogUpdateForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocCatalogVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Optional; + +/** + * 帮助文档 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class HelpDocCatalogService { + + @Resource + private HelpDocCatalogDao helpDocCatalogDao; + + @Resource + private HelpDocDao helpDocDao; + + /** + * 查询全部目录 + * + * @return + */ + public List getAll() { + return SmartBeanUtil.copyList(helpDocCatalogDao.selectList(null), HelpDocCatalogVO.class); + } + + /** + * 添加目录 + * + * @param helpDocCatalogAddForm + * @return + */ + public synchronized ResponseDTO add(HelpDocCatalogAddForm helpDocCatalogAddForm) { + List helpDocCatalogList = getAll(); + Optional exist = helpDocCatalogList.stream().filter(e -> helpDocCatalogAddForm.getName().equals(e.getName())).findFirst(); + if (exist.isPresent()) { + return ResponseDTO.userErrorParam("存在相同名称的目录了"); + } + + helpDocCatalogDao.insert(SmartBeanUtil.copy(helpDocCatalogAddForm, HelpDocCatalogEntity.class)); + return ResponseDTO.ok(); + } + + /** + * 更新目录 + * + * @param updateForm + * @return + */ + public synchronized ResponseDTO update(HelpDocCatalogUpdateForm updateForm) { + HelpDocCatalogEntity helpDocCatalogEntity = helpDocCatalogDao.selectById(updateForm.getHelpDocCatalogId()); + if (helpDocCatalogEntity == null) { + return ResponseDTO.userErrorParam("目录不存在"); + } + + List helpDocCatalogList = getAll(); + Optional exist = helpDocCatalogList.stream().filter(e -> updateForm.getName().equals(e.getName())).findFirst(); + if (exist.isPresent() && !exist.get().getHelpDocCatalogId().equals(updateForm.getHelpDocCatalogId())) { + return ResponseDTO.userErrorParam("存在相同名称的目录了"); + } + helpDocCatalogDao.updateById(SmartBeanUtil.copy(updateForm, HelpDocCatalogEntity.class)); + return ResponseDTO.ok(); + } + + /** + * 删除目录(如果有子目录、或者有帮助文档,则不能删除) + * + * @param helpDocCatalogId + * @return + */ + public synchronized ResponseDTO delete(Long helpDocCatalogId) { + if (helpDocCatalogId == null) { + return ResponseDTO.ok(); + } + + HelpDocCatalogEntity helpDocCatalogEntity = helpDocCatalogDao.selectById(helpDocCatalogId); + if (helpDocCatalogEntity == null) { + return ResponseDTO.userErrorParam("目录不存在"); + } + + //如果有子目录,则不能删除 + Optional existOptional = getAll().stream().filter(e -> helpDocCatalogId.equals(e.getParentId())).findFirst(); + if (existOptional.isPresent()) { + return ResponseDTO.userErrorParam("存在子目录:" + existOptional.get().getName()); + } + + //查询是否有帮助文档 + List helpDocVOList = helpDocDao.queryHelpDocByCatalogId(helpDocCatalogId); + if (CollectionUtils.isNotEmpty(helpDocVOList)) { + return ResponseDTO.userErrorParam("目录下存在文档,不能删除"); + } + helpDocCatalogDao.deleteById(helpDocCatalogId); + return ResponseDTO.ok(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocService.java new file mode 100644 index 0000000..856bada --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocService.java @@ -0,0 +1,120 @@ +package net.lab1024.sa.base.module.support.helpdoc.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.base.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocAddForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocQueryForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocUpdateForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.base.module.support.helpdoc.manager.HelpDocManager; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 后台管理业务 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class HelpDocService { + + @Resource + private HelpDocDao helpDocDao; + + @Resource + private HelpDocManager helpDaoManager; + + + /** + * 查询 帮助文档 + * + * @param queryForm + * @return + */ + public PageResult query(HelpDocQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = helpDocDao.query(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + * + * @param addForm + * @return + */ + public ResponseDTO add(HelpDocAddForm addForm) { + HelpDocEntity helpDaoEntity = SmartBeanUtil.copy(addForm, HelpDocEntity.class); + helpDaoManager.save(helpDaoEntity, addForm.getRelationList()); + return ResponseDTO.ok(); + } + + + /** + * 更新 + * + * @param updateForm + * @return + */ + public ResponseDTO update(HelpDocUpdateForm updateForm) { + // 更新 + HelpDocEntity helpDaoEntity = SmartBeanUtil.copy(updateForm, HelpDocEntity.class); + helpDaoManager.update(helpDaoEntity, updateForm.getRelationList()); + return ResponseDTO.ok(); + } + + + /** + * 删除 + * + * @param helpDocId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long helpDocId) { + HelpDocEntity helpDaoEntity = helpDocDao.selectById(helpDocId); + if (helpDaoEntity != null) { + helpDocDao.deleteById(helpDocId); + helpDocDao.deleteRelation(helpDocId); + } + return ResponseDTO.ok(); + } + + /** + * 获取详情 + * + * @param helpDocId + * @return + */ + public HelpDocDetailVO getDetail(Long helpDocId) { + HelpDocEntity helpDaoEntity = helpDocDao.selectById(helpDocId); + HelpDocDetailVO detail = SmartBeanUtil.copy(helpDaoEntity, HelpDocDetailVO.class); + if (detail != null) { + detail.setRelationList(helpDocDao.queryRelationByHelpDoc(helpDocId)); + } + return detail; + } + + /** + * 获取详情 + * + * @param relationId + * @return + */ + public List queryHelpDocByRelationId(Long relationId) { + return helpDocDao.queryHelpDocByRelationId(relationId); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocUserService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocUserService.java new file mode 100644 index 0000000..5fc3e67 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocUserService.java @@ -0,0 +1,85 @@ +package net.lab1024.sa.base.module.support.helpdoc.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.base.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.base.module.support.helpdoc.domain.form.HelpDocViewRecordQueryForm; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.base.module.support.helpdoc.domain.vo.HelpDocViewRecordVO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 用户查看 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class HelpDocUserService { + + @Resource + private HelpDocDao helpDocDao; + + + /** + * 查询全部 帮助文档 + * + * @return + */ + public ResponseDTO> queryAllHelpDocList() { + return ResponseDTO.ok(helpDocDao.queryAllHelpDocList()); + } + + + /** + * 查询我的 待查看的 帮助文档清单 + * + * @return + */ + public ResponseDTO view(RequestUser requestUser, Long helpDocId) { + HelpDocEntity helpDocEntity = helpDocDao.selectById(helpDocId); + if (helpDocEntity == null) { + return ResponseDTO.userErrorParam("帮助文档不存在"); + } + + HelpDocDetailVO helpDocDetailVO = SmartBeanUtil.copy(helpDocEntity, HelpDocDetailVO.class); + long viewCount = helpDocDao.viewRecordCount(helpDocId, requestUser.getUserId()); + if (viewCount == 0) { + helpDocDao.insertViewRecord(helpDocId, requestUser.getUserId(), requestUser.getUserName(), requestUser.getIp(), requestUser.getUserAgent(), 1); + helpDocDao.updateViewCount(helpDocId, 1, 1); + helpDocDetailVO.setPageViewCount(helpDocDetailVO.getPageViewCount() + 1); + helpDocDetailVO.setUserViewCount(helpDocDetailVO.getUserViewCount() + 1); + } else { + helpDocDao.updateViewRecord(helpDocId, requestUser.getUserId(), requestUser.getIp(), requestUser.getUserAgent()); + helpDocDao.updateViewCount(helpDocId, 0, 1); + helpDocDetailVO.setPageViewCount(helpDocDetailVO.getPageViewCount() + 1); + } + + return ResponseDTO.ok(helpDocDetailVO); + } + + + /** + * 分页查询 查看记录 + * + * @param helpDocViewRecordQueryForm + * @return + */ + public PageResult queryViewRecord(HelpDocViewRecordQueryForm helpDocViewRecordQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(helpDocViewRecordQueryForm); + List noticeViewRecordVOS = helpDocDao.queryViewRecordList(page, helpDocViewRecordQueryForm); + return SmartPageUtil.convert2PageResult(page, noticeViewRecordVOS); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager.java new file mode 100644 index 0000000..044ddf6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager.java @@ -0,0 +1,164 @@ +package net.lab1024.sa.base.module.support.job.api; + +import cn.hutool.core.util.IdUtil; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.job.api.domain.SmartJobMsg; +import net.lab1024.sa.base.module.support.job.config.SmartJobAutoConfiguration; +import net.lab1024.sa.base.module.support.job.core.SmartJob; +import net.lab1024.sa.base.module.support.job.core.SmartJobExecutor; +import net.lab1024.sa.base.module.support.job.core.SmartJobLauncher; +import net.lab1024.sa.base.module.support.job.repository.SmartJobRepository; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import org.redisson.api.RLock; +import org.redisson.api.RTopic; +import org.redisson.api.RedissonClient; +import org.redisson.api.listener.MessageListener; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +import javax.annotation.PreDestroy; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * smart job 执行端管理 + * 分布式系统之间 用发布/订阅消息的形式 来管理多个job + * + * @author huke + * @date 2024/6/22 20:31 + */ +@ConditionalOnBean(SmartJobAutoConfiguration.class) +@Slf4j +@Service +public class SmartJobClientManager { + + private final SmartJobLauncher jobLauncher; + + private final SmartJobRepository jobRepository; + + private final List jobInterfaceList; + + private static final String EXECUTE_LOCK = "smart-job-lock-msg-execute-"; + + private static final String TOPIC = "smart-job-instance"; + + private final RedissonClient redissonClient; + + private final RTopic topic; + + private final SmartJobMsgListener jobMsgListener; + + public SmartJobClientManager(SmartJobLauncher jobLauncher, + SmartJobRepository jobRepository, + List jobInterfaceList, + RedissonClient redissonClient) { + this.jobLauncher = jobLauncher; + this.jobRepository = jobRepository; + this.jobInterfaceList = jobInterfaceList; + this.redissonClient = redissonClient; + + // 添加监听器 + this.topic = redissonClient.getTopic(TOPIC); + this.jobMsgListener = new SmartJobMsgListener(); + topic.addListener(SmartJobMsg.class, jobMsgListener); + log.info("==== SmartJob ==== client-manager init"); + } + + /** + * 发布消息 + */ + public void publishToClient(SmartJobMsg msgDTO) { + msgDTO.setMsgId(IdUtil.fastSimpleUUID()); + topic.publish(msgDTO); + } + + /** + * 处理消息 + */ + private class SmartJobMsgListener implements MessageListener { + + @Override + public void onMessage(CharSequence channel, SmartJobMsg msg) { + log.info("==== SmartJob ==== on-message :{}", msg); + // 判断消息类型 业务简单就直接判断 复杂的话可以策略模式 + SmartJobMsg.MsgTypeEnum msgType = msg.getMsgType(); + // 更新任务 + if (SmartJobMsg.MsgTypeEnum.UPDATE_JOB == msgType) { + updateJob(msg.getJobId()); + } + // 执行任务 + if (SmartJobMsg.MsgTypeEnum.EXECUTE_JOB == msgType) { + executeJob(msg); + } + } + } + + /** + * 获取任务执行类 + * + * @param jobClass + * @return + */ + private Optional queryJobImpl(String jobClass) { + return jobInterfaceList.stream().filter(e -> Objects.equals(e.getClassName(), jobClass)).findFirst(); + } + + /** + * 更新任务 + * + * @param jobId + */ + private void updateJob(Integer jobId) { + SmartJobEntity jobEntity = jobRepository.getJobDao().selectById(jobId); + if (null == jobEntity) { + return; + } + jobLauncher.startOrRefreshJob(Lists.newArrayList(jobEntity)); + } + + /** + * 立即执行任务 + * + * @param msg + */ + private void executeJob(SmartJobMsg msg) { + Integer jobId = msg.getJobId(); + SmartJobEntity jobEntity = jobRepository.getJobDao().selectById(jobId); + if (null == jobEntity) { + return; + } + // 获取定时任务实现类 + Optional optional = this.queryJobImpl(jobEntity.getJobClass()); + if (!optional.isPresent()) { + return; + } + + // 获取执行锁 无需主动释放 + RLock rLock = redissonClient.getLock(EXECUTE_LOCK + msg.getMsgId()); + try { + boolean getLock = rLock.tryLock(0, 20, TimeUnit.SECONDS); + if (!getLock) { + return; + } + } catch (InterruptedException e) { + log.error("==== SmartJob ==== msg execute err:", e); + return; + } + + // 通过执行器 执行任务 + jobEntity.setParam(msg.getParam()); + SmartJobExecutor jobExecutor = new SmartJobExecutor(jobEntity, jobRepository, optional.get(), redissonClient); + jobExecutor.execute(msg.getUpdateName()); + } + + + @PreDestroy + public void destroy() { + topic.removeListener(jobMsgListener); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/SmartJobService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/SmartJobService.java new file mode 100644 index 0000000..e55816d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/SmartJobService.java @@ -0,0 +1,296 @@ +package net.lab1024.sa.base.module.support.job.api; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.job.api.domain.*; +import net.lab1024.sa.base.module.support.job.config.SmartJobAutoConfiguration; +import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum; +import net.lab1024.sa.base.module.support.job.constant.SmartJobUtil; +import net.lab1024.sa.base.module.support.job.repository.SmartJobDao; +import net.lab1024.sa.base.module.support.job.repository.SmartJobLogDao; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobLogEntity; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 定时任务 接口业务管理 + * 如果不需要通过接口管理定时任务 可以删除此类 + * + * @author huke + * @date 2024/6/17 20:41 + */ +@ConditionalOnBean(SmartJobAutoConfiguration.class) +@Service +public class SmartJobService { + + @Resource + private SmartJobDao jobDao; + + @Resource + private SmartJobLogDao jobLogDao; + + @Resource + private SmartJobClientManager jobClientManager; + + /** + * 查询 定时任务详情 + * + * @param jobId + * @return + */ + public ResponseDTO queryJobInfo(Integer jobId) { + SmartJobEntity jobEntity = jobDao.selectById(jobId); + if (null == jobEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + SmartJobVO jobVO = SmartBeanUtil.copy(jobEntity, SmartJobVO.class); + // 处理设置job详情 + this.handleJobInfo(Lists.newArrayList(jobVO)); + return ResponseDTO.ok(jobVO); + } + + /** + * 分页查询 定时任务 + * + * @param queryForm + * @return + */ + public ResponseDTO> queryJob(SmartJobQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List jobList = jobDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, jobList); + // 处理设置job详情 + this.handleJobInfo(jobList); + return ResponseDTO.ok(pageResult); + } + + /** + * 处理设置 任务信息 + * + * @param jobList + */ + private void handleJobInfo(List jobList) { + if (CollectionUtils.isEmpty(jobList)) { + return; + } + // 查询最后一次执行记录 + List logIdList = jobList.stream().map(SmartJobVO::getLastExecuteLogId).filter(Objects::nonNull).collect(Collectors.toList()); + Map lastLogMap = Collections.emptyMap(); + if (CollectionUtils.isNotEmpty(logIdList)) { + lastLogMap = jobLogDao.selectBatchIds(logIdList) + .stream() + .collect(Collectors.toMap(SmartJobLogEntity::getLogId, e -> SmartBeanUtil.copy(e, SmartJobLogVO.class))); + } + + // 循环处理任务信息 + for (SmartJobVO jobVO : jobList) { + // 设置最后一次执行记录 + Long lastExecuteLogId = jobVO.getLastExecuteLogId(); + if (null != lastExecuteLogId) { + jobVO.setLastJobLog(lastLogMap.get(lastExecuteLogId)); + } + // 计算未来5次执行时间 + if (jobVO.getEnabledFlag()) { + List nextTimeList = SmartJobUtil.queryNextTimeFromNow(jobVO.getTriggerType(), jobVO.getTriggerValue(), jobVO.getLastExecuteTime(), 5); + jobVO.setNextJobExecuteTimeList(nextTimeList); + } + } + } + + /** + * 分页查询 定时任务-执行记录 + * + * @param queryForm + * @return + */ + public ResponseDTO> queryJobLog(SmartJobLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List jobList = jobLogDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, jobList); + return ResponseDTO.ok(pageResult); + } + + /** + * 添加定时任务 + * + * @param addForm + * @return + */ + public synchronized ResponseDTO addJob(SmartJobAddForm addForm) { + // 校验参数 + ResponseDTO checkRes = this.checkParam(addForm); + if (!checkRes.getOk()) { + return checkRes; + } + + // 校验重复的执行类 + SmartJobEntity existJobClass = jobDao.selectByJobClass(addForm.getJobClass()); + if (null != existJobClass && !existJobClass.getDeletedFlag()) { + return ResponseDTO.userErrorParam("已经存在相同的执行类"); + } + + // 添加数据 + SmartJobEntity jobEntity = SmartBeanUtil.copy(addForm, SmartJobEntity.class); + jobDao.insert(jobEntity); + + // 更新执行端 + SmartJobMsg jobMsg = new SmartJobMsg(); + jobMsg.setJobId(jobEntity.getJobId()); + jobMsg.setMsgType(SmartJobMsg.MsgTypeEnum.UPDATE_JOB); + jobMsg.setUpdateName(addForm.getUpdateName()); + jobClientManager.publishToClient(jobMsg); + return ResponseDTO.ok(); + } + + /** + * 更新定时任务 + * + * @param updateForm + * @return + */ + public synchronized ResponseDTO updateJob(SmartJobUpdateForm updateForm) { + // 校验参数 + Integer jobId = updateForm.getJobId(); + SmartJobEntity jobEntity = jobDao.selectById(jobId); + if (null == jobEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + ResponseDTO checkRes = this.checkParam(updateForm); + if (!checkRes.getOk()) { + return checkRes; + } + + // 校验重复的执行类 + SmartJobEntity existJobClass = jobDao.selectByJobClass(updateForm.getJobClass()); + if (null != existJobClass && !existJobClass.getDeletedFlag() && !existJobClass.getJobId().equals(jobId)) { + return ResponseDTO.userErrorParam("已经存在相同的执行类"); + } + + // 更新数据 + jobEntity = SmartBeanUtil.copy(updateForm, SmartJobEntity.class); + jobDao.updateById(jobEntity); + + // 更新执行端 + SmartJobMsg jobMsg = new SmartJobMsg(); + jobMsg.setJobId(jobId); + jobMsg.setMsgType(SmartJobMsg.MsgTypeEnum.UPDATE_JOB); + jobMsg.setUpdateName(updateForm.getUpdateName()); + jobClientManager.publishToClient(jobMsg); + return ResponseDTO.ok(); + } + + /** + * 校验参数 + * 如需其他校验,请自行添加校验逻辑 + * + * @param addForm + * @return + */ + private ResponseDTO checkParam(SmartJobAddForm addForm) { + // 校验触发时间配置 + String triggerType = addForm.getTriggerType(); + String triggerValue = addForm.getTriggerValue(); + if (SmartJobTriggerTypeEnum.CRON.equalsValue(triggerType) && !SmartJobUtil.checkCron(triggerValue)) { + return ResponseDTO.userErrorParam("cron表达式错误"); + } + if (SmartJobTriggerTypeEnum.FIXED_DELAY.equalsValue(triggerType) && !SmartJobUtil.checkFixedDelay(triggerValue)) { + return ResponseDTO.userErrorParam("固定间隔配置错误:必须是大于0的整数"); + } + // 校验job class + return SmartJobUtil.checkJobClass(addForm.getJobClass()); + } + + /** + * 更新定时任务-是否开启 + * + * @param updateForm + * @return + */ + public ResponseDTO updateJobEnabled(SmartJobEnabledUpdateForm updateForm) { + Integer jobId = updateForm.getJobId(); + SmartJobEntity jobEntity = jobDao.selectById(jobId); + if (null == jobEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + Boolean enabledFlag = updateForm.getEnabledFlag(); + if (Objects.equals(enabledFlag, jobEntity.getEnabledFlag())) { + return ResponseDTO.ok(); + } + // 更新数据 + jobEntity = new SmartJobEntity(); + jobEntity.setJobId(jobId); + jobEntity.setEnabledFlag(enabledFlag); + jobEntity.setUpdateName(updateForm.getUpdateName()); + jobDao.updateById(jobEntity); + + // 更新执行端 + SmartJobMsg jobMsg = new SmartJobMsg(); + jobMsg.setJobId(jobId); + jobMsg.setMsgType(SmartJobMsg.MsgTypeEnum.UPDATE_JOB); + jobMsg.setUpdateName(updateForm.getUpdateName()); + jobClientManager.publishToClient(jobMsg); + return ResponseDTO.ok(); + } + + /** + * 执行定时任务 + * 忽略任务的开启状态,立即执行一次 + * + * @param executeForm + * @return + */ + public ResponseDTO execute(SmartJobExecuteForm executeForm) { + Integer jobId = executeForm.getJobId(); + SmartJobEntity jobEntity = jobDao.selectById(jobId); + if (null == jobEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 更新执行端 + SmartJobMsg jobMsg = new SmartJobMsg(); + jobMsg.setJobId(jobId); + jobMsg.setParam(executeForm.getParam()); + jobMsg.setMsgType(SmartJobMsg.MsgTypeEnum.EXECUTE_JOB); + jobMsg.setUpdateName(executeForm.getUpdateName()); + jobClientManager.publishToClient(jobMsg); + return ResponseDTO.ok(); + } + + /** + * 移除定时任务 + * 物理删除 + * + * @return + * @author huke + */ + public synchronized ResponseDTO deleteJob(Integer jobId, RequestUser requestUser) { + // 删除任务 + jobDao.updateDeletedFlag(jobId, Boolean.TRUE); + + // 更新执行端 + SmartJobMsg jobMsg = new SmartJobMsg(); + jobMsg.setJobId(jobId); + jobMsg.setMsgType(SmartJobMsg.MsgTypeEnum.UPDATE_JOB); + jobMsg.setUpdateName(requestUser.getUserName()); + jobClientManager.publishToClient(jobMsg); + return ResponseDTO.ok(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobAddForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobAddForm.java new file mode 100644 index 0000000..4dcea39 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobAddForm.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 定时任务 添加 + * + * @author huke + * @date 2024/12/19 19:30 + */ +@Data +public class SmartJobAddForm { + + @Schema(description = "任务名称") + @NotBlank(message = "任务名称不能为空") + @Length(max = 100, message = "任务名称最多100字符") + private String jobName; + + @Schema(description = "任务执行类") + @NotBlank(message = "任务执行类不能为空") + @Length(max = 200, message = "任务执行类最多200字符") + private String jobClass; + + @SchemaEnum(desc = "触发类型", value = SmartJobTriggerTypeEnum.class) + @CheckEnum(value = SmartJobTriggerTypeEnum.class, required = true, message = "触发类型错误") + private String triggerType; + + @Schema(description = "触发配置") + @NotBlank(message = "触发配置不能为空") + @Length(max = 100, message = "触发配置最多100字符") + private String triggerValue; + + @Schema(description = "定时任务参数|可选") + @Length(max = 1000, message = "定时任务参数最多1000字符") + private String param; + + @Schema(description = "是否开启") + @NotNull(message = "是否开启不能为空") + private Boolean enabledFlag; + + @Schema(description = "备注") + @Length(max = 250, message = "任务备注最多250字符") + private String remark; + + @NotNull(message = "排序不能为空") + @Schema(description = "排序") + private Integer sort; + + @Schema(hidden = true) + private String updateName; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobEnabledUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobEnabledUpdateForm.java new file mode 100644 index 0000000..d92a9aa --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobEnabledUpdateForm.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 定时任务-更新-开启状态 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Data +public class SmartJobEnabledUpdateForm { + + @Schema(description = "任务id") + @NotNull(message = "任务id不能为空") + private Integer jobId; + + @Schema(description = "是否启用") + @NotNull(message = "是否启用不能为空") + private Boolean enabledFlag; + + @Schema(hidden = true) + private String updateName; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobExecuteForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobExecuteForm.java new file mode 100644 index 0000000..a4d3b91 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobExecuteForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 定时任务-手动执行 + * + * @author huke + * @date 2024/6/18 20:30 + */ +@Data +public class SmartJobExecuteForm { + + @Schema(description = "任务id") + @NotNull(message = "任务id不能为空") + private Integer jobId; + + @Schema(description = "定时任务参数|可选") + @Length(max = 2000, message = "定时任务参数最多2000字符") + private String param; + + @Schema(hidden = true) + private String updateName; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogQueryForm.java new file mode 100644 index 0000000..f405e7d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogQueryForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * 定时任务-执行记录 分页查询 + * + * @author huke + * @date 2024/6/17 20:50 + */ +@Data +public class SmartJobLogQueryForm extends PageParam { + + @Schema(description = "搜索词|可选") + @Length(max = 50, message = "搜索词最多50字符") + private String searchWord; + + @Schema(description = "任务id|可选") + private Integer jobId; + + @Schema(description = "是否成功|可选") + private Boolean successFlag; + + @Schema(description = "开始时间|可选", example = "2024-06-06") + private LocalDate startTime; + + @Schema(description = "截止时间|可选", example = "2025-10-15") + private LocalDate endTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogVO.java new file mode 100644 index 0000000..dc60cb7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogVO.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 定时任务-执行记录 vo + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Data +public class SmartJobLogVO { + + @Schema(description = "logId") + private Long logId; + + @Schema(description = "任务id") + private Integer jobId; + + @Schema(description = "任务名称") + private String jobName; + + @Schema(description = "定时任务参数|可选") + private String param; + + @Schema(description = "执行结果是否成功") + private Boolean successFlag; + + @Schema(description = "开始执行时间") + private LocalDateTime executeStartTime; + + @Schema(description = "执行时长-毫秒") + private Long executeTimeMillis; + + @Schema(description = "执行结果描述") + private String executeResult; + + @Schema(description = "执行结束时间") + private LocalDateTime executeEndTime; + + @Schema(description = "ip") + private String ip; + + @Schema(description = "进程id") + private String processId; + + @Schema(description = "程序目录") + private String programPath; + + private String createName; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg.java new file mode 100644 index 0000000..c7cba95 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 定时任务 发布/订阅消息对象 + * + * @author huke + * @date 2024/6/20 21:10 + */ +@Data +public class SmartJobMsg { + + /** + * 消息id 无需设置 + */ + private String msgId; + + /** + * 任务id + */ + private Integer jobId; + + /** + * 任务参数 + */ + private String param; + + /** + * 消息类型 + */ + private MsgTypeEnum msgType; + + /** + * 更新人 + */ + private String updateName; + + @Getter + @AllArgsConstructor + public enum MsgTypeEnum implements BaseEnum { + + /** + * 1 更新任务 + */ + UPDATE_JOB(1, "更新任务"), + + EXECUTE_JOB(2, "执行任务"), + + ; + + private final Integer value; + + private final String desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobQueryForm.java new file mode 100644 index 0000000..39a56c7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobQueryForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum; +import org.hibernate.validator.constraints.Length; + +/** + * 定时任务 分页查询 + * + * @author huke + * @date 2024/6/17 20:50 + */ +@Data +public class SmartJobQueryForm extends PageParam { + + @Schema(description = "搜索词|可选") + @Length(max = 50, message = "搜索词最多50字符") + private String searchWord; + + @SchemaEnum(desc = "触发类型", value = SmartJobTriggerTypeEnum.class) + @CheckEnum(value = SmartJobTriggerTypeEnum.class, message = "触发类型错误") + private String triggerType; + + @Schema(description = "是否启用|可选") + private Boolean enabledFlag; + + @Schema(description = "是否删除|可选") + private Boolean deletedFlag; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobUpdateForm.java new file mode 100644 index 0000000..56a7413 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobUpdateForm.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 定时任务 更新 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Data +public class SmartJobUpdateForm extends SmartJobAddForm { + + @Schema(description = "任务id") + @NotNull(message = "任务id不能为空") + private Integer jobId; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobVO.java new file mode 100644 index 0000000..d83d98b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/api/domain/SmartJobVO.java @@ -0,0 +1,66 @@ +package net.lab1024.sa.base.module.support.job.api.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.json.serializer.enumeration.EnumSerialize; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 定时任务 vo + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Data +public class SmartJobVO { + + @Schema(description = "任务id") + private Integer jobId; + + @Schema(description = "任务名称") + private String jobName; + + @Schema(description = "执行类") + private String jobClass; + + @SchemaEnum(desc = "触发类型", value = SmartJobTriggerTypeEnum.class) + @EnumSerialize(SmartJobTriggerTypeEnum.class) + private String triggerType; + + @Schema(description = "触发配置") + private String triggerValue; + + @Schema(description = "定时任务参数|可选") + private String param; + + @Schema(description = "是否启用") + private Boolean enabledFlag; + + @Schema(description = "最后一执行时间") + private LocalDateTime lastExecuteTime; + + @Schema(description = "最后一次执行记录id") + private Long lastExecuteLogId; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序") + private Integer sort; + + private String updateName; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + + @Schema(description = "上次执行记录") + private SmartJobLogVO lastJobLog; + + @Schema(description = "未来N次任务执行时间") + private List nextJobExecuteTimeList; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/config/SmartJobAutoConfiguration.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/config/SmartJobAutoConfiguration.java new file mode 100644 index 0000000..25ad872 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/config/SmartJobAutoConfiguration.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.job.config; + +import net.lab1024.sa.base.module.support.job.core.SmartJob; +import net.lab1024.sa.base.module.support.job.core.SmartJobLauncher; +import net.lab1024.sa.base.module.support.job.repository.SmartJobRepository; +import org.redisson.api.RedissonClient; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +/** + * 定时任务 配置 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Configuration +@EnableConfigurationProperties(SmartJobConfig.class) +@ConditionalOnProperty( + prefix = SmartJobConfig.CONFIG_PREFIX, + name = "enabled", + havingValue = "true" +) +public class SmartJobAutoConfiguration { + + private final SmartJobConfig jobConfig; + + private final SmartJobRepository jobRepository; + + private final List jobInterfaceList; + + public SmartJobAutoConfiguration(SmartJobConfig jobConfig, + SmartJobRepository jobRepository, + List jobInterfaceList) { + this.jobConfig = jobConfig; + this.jobRepository = jobRepository; + this.jobInterfaceList = jobInterfaceList; + } + + /** + * 定时任务启动器 + * + * @return + */ + @Bean + public SmartJobLauncher initJobLauncher(RedissonClient redissonClient) { + return new SmartJobLauncher(jobConfig, jobRepository, jobInterfaceList, redissonClient); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/config/SmartJobConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/config/SmartJobConfig.java new file mode 100644 index 0000000..d2bee0d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/config/SmartJobConfig.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.base.module.support.job.config; + + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * smart job 配置 + * 与配置文件参数对应 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@ConfigurationProperties(prefix = SmartJobConfig.CONFIG_PREFIX) +@Data +public class SmartJobConfig { + + public static final String CONFIG_PREFIX = "smart.job"; + + /** + * 任务执行核心线程数 偶数 默认2 + */ + private Integer corePoolSize = 2; + + /** + * 任务延迟初始化 默认30秒 + */ + private Integer initDelay = 30; + + /** + * 数据库配置检测-开关 默认开启 + */ + private Boolean dbRefreshEnabled = true; + + /** + * 数据库配置检测-执行间隔 默认120秒 + */ + private Integer dbRefreshInterval = 120; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobConst.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobConst.java new file mode 100644 index 0000000..4409ad3 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobConst.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.base.module.support.job.constant; + +/** + * smart job 常量 + * + * @author huke + * @date 2024/6/19 20:25 + */ +public class SmartJobConst { + + public static final String SYSTEM_NAME = "system"; + + public static final String LOGO = " _____ __ __ __ \n" + + " / ___/____ ___ ____ ______/ /_ / /___ / /_ \n" + + " \\__ \\/ __ `__ \\/ __ `/ ___/ __/ __ / / __ \\/ __ \\\n" + + " ___/ / / / / / / /_/ / / / /_ / /_/ / /_/ / /_/ /\n" + + "/____/_/ /_/ /_/\\__,_/_/ \\__/ \\____/\\____/_.___/ \n" + + "-->任务执行线程池:%s\n" + + "-->任务初始化延迟:%s秒\n" + + "-->数据库配置检测:%s\n\n"; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobTriggerTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobTriggerTypeEnum.java new file mode 100644 index 0000000..c2368c6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobTriggerTypeEnum.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.module.support.job.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * job 任务触发类型 枚举类 + * + * @author huke + * @date 2024年6月29日 + **/ +@AllArgsConstructor +@Getter +public enum SmartJobTriggerTypeEnum implements BaseEnum { + + /** + * 1 cron表达式 + */ + CRON("cron", "cron表达式"), + + FIXED_DELAY("fixed_delay", "固定间隔"), + + ; + + private final String value; + + private final String desc; +} + diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobUtil.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobUtil.java new file mode 100644 index 0000000..ac21b3d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/constant/SmartJobUtil.java @@ -0,0 +1,210 @@ +package net.lab1024.sa.base.module.support.job.constant; + +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.job.core.SmartJob; +import org.springframework.scheduling.support.CronExpression; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * smart job util + * + * @author huke + * @date 2024/6/18 20:00 + */ +public class SmartJobUtil { + + private SmartJobUtil() { + } + + /** + * 校验cron表达式 是否合法 + * + * @param cron + * @return + */ + public static boolean checkCron(String cron) { + return CronExpression.isValidExpression(cron); + } + + /** + * 校验固定间隔 值是否合法 + * + * @param val + * @return + */ + public static boolean checkFixedDelay(String val) { + int intVal; + try { + intVal = Integer.parseInt(val); + } catch (NumberFormatException e) { + return false; + } + return intVal > 0; + } + + /** + * 打印一些展示信息到控制台 + * 环保绿 + * + * @param info + */ + public static void printInfo(String info) { + System.out.printf("\033[32;1m %s \033[0m", info); + } + + /** + * 查询未来N次执行时间 从最后一次时间时间 开始计算 + * + * @param triggerType + * @param triggerVal + * @param lastExecuteTime + * @param num + * @return + */ + public static List queryNextTimeFromLast(String triggerType, + String triggerVal, + LocalDateTime lastExecuteTime, + int num) { + List nextTimeList = null; + if (SmartJobTriggerTypeEnum.CRON.equalsValue(triggerType)) { + nextTimeList = SmartJobUtil.queryNextTime(triggerVal, lastExecuteTime, num); + } else if (SmartJobTriggerTypeEnum.FIXED_DELAY.equalsValue(triggerType)) { + nextTimeList = SmartJobUtil.queryNextTime(getFixedDelayVal(triggerVal), lastExecuteTime, num); + } + return nextTimeList; + } + + /** + * 查询未来N次执行时间 从当前时间 开始计算 + * + * @param triggerType + * @param triggerVal + * @param lastExecuteTime + * @param num + * @return + */ + public static List queryNextTimeFromNow(String triggerType, + String triggerVal, + LocalDateTime lastExecuteTime, + int num) { + LocalDateTime nowTime = LocalDateTime.now(); + List nextTimeList = null; + if (SmartJobTriggerTypeEnum.CRON.equalsValue(triggerType)) { + nextTimeList = SmartJobUtil.queryNextTime(triggerVal, nowTime, num); + } else if (SmartJobTriggerTypeEnum.FIXED_DELAY.equalsValue(triggerType)) { + Integer fixedDelay = getFixedDelayVal(triggerVal); + LocalDateTime startTime = null == lastExecuteTime || lastExecuteTime.plusSeconds(fixedDelay).isBefore(nowTime) + ? nowTime : lastExecuteTime; + nextTimeList = SmartJobUtil.queryNextTime(fixedDelay, startTime, num); + } + return nextTimeList; + } + + /** + * 根据cron表达式 计算N次执行时间 + * + * @param cron + * @param startTime + * @param num + * @return + */ + public static List queryNextTime(String cron, LocalDateTime startTime, int num) { + if (null == startTime) { + return Collections.emptyList(); + } + CronExpression parse = CronExpression.parse(cron); + List timeList = new ArrayList<>(num); + for (int i = 0; i < num; i++) { + startTime = parse.next(startTime); + timeList.add(startTime); + } + return timeList; + } + + /** + * 根据 固定间隔 计算N次执行时间 + * + * @param fixDelaySecond + * @param startTime + * @param num + * @return + */ + public static List queryNextTime(Integer fixDelaySecond, LocalDateTime startTime, int num) { + if (null == startTime) { + return Collections.emptyList(); + } + List timeList = new ArrayList<>(num); + for (int i = 0; i < num; i++) { + startTime = startTime.plusSeconds(fixDelaySecond); + timeList.add(startTime); + } + return timeList; + } + + /** + * 获取固定间隔时间 + * + * @param val + * @return + */ + public static Integer getFixedDelayVal(String val) { + return Integer.parseInt(val); + } + + /** + * 获取当前 Java 应用程序的工作目录 + * + * @return + */ + public static String getProgramPath() { + return System.getProperty("user.dir"); + } + + /** + * 获取当前 Java 应用程序的进程id + * + * @return + */ + public static String getProcessId() { + RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); + return runtime.getName().split("@")[0]; + } + + + /** + * 根据className 判断job class + */ + public static ResponseDTO checkJobClass(String className) { + try { + Class aClass = Class.forName(className); + // 判断是否实现了 SmartJob + if (!SmartJob.class.isAssignableFrom(aClass)) { + return ResponseDTO.userErrorParam(className + " 执行类没有实现 SmartJob 接口"); + } + } catch (ClassNotFoundException e) { + return ResponseDTO.userErrorParam("没有在代码中发现执行类:" + className); + } + return ResponseDTO.ok(); + } + + + public static void main(String[] args) { + LocalDateTime startTime = LocalDateTime.now(); + List timeList = SmartJobUtil.queryNextTime("5 * * * * *", startTime, 3); + System.out.println(timeList); + + timeList = SmartJobUtil.queryNextTime(10, startTime, 3); + System.out.println(timeList); + + System.out.println("project path ->" + getProgramPath()); + System.out.println("project process id ->" + getProcessId()); + ResponseDTO res = checkJobClass("net.lab1024.sa.base.module.support.job.sample.SmartJobSample1"); + System.out.println(res.getMsg()); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJob.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJob.java new file mode 100644 index 0000000..7549642 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJob.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.job.core; + +/** + * 定时任务 执行接口 + * + * @author huke + * @date 2024/6/17 21:30 + */ +public interface SmartJob { + + /** + * 默认方法 + * 获取当前任务类名 + * + * @return + */ + default String getClassName() { + return this.getClass().getName(); + } + + /** + * 执行定时任务 + * + * @param param 可选参数 任务不需要时不用管 + * @return 可null, 自行组织语言描述执行结果,例如:本次处理数据N条 等 + */ + String run(String param); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobExecutor.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobExecutor.java new file mode 100644 index 0000000..721410a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobExecutor.java @@ -0,0 +1,168 @@ +package net.lab1024.sa.base.module.support.job.core; + +import cn.hutool.core.exceptions.ExceptionUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.util.SmartIpUtil; +import net.lab1024.sa.base.module.support.job.constant.SmartJobConst; +import net.lab1024.sa.base.module.support.job.constant.SmartJobUtil; +import net.lab1024.sa.base.module.support.job.repository.SmartJobRepository; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobLogEntity; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.util.StopWatch; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; + +/** + * 定时任务 执行器 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Slf4j +public class SmartJobExecutor implements Runnable { + + private final SmartJobEntity jobEntity; + + private final SmartJobRepository jobRepository; + + private final SmartJob jobInterface; + + private final RedissonClient redissonClient; + + private static final String EXECUTE_LOCK = "smart-job-lock-execute-"; + + public SmartJobExecutor(SmartJobEntity jobEntity, + SmartJobRepository jobRepository, + SmartJob jobInterface, + RedissonClient redissonClient) { + this.jobEntity = jobEntity; + this.jobRepository = jobRepository; + this.jobInterface = jobInterface; + this.redissonClient = redissonClient; + } + + /** + * 系统线程执行 + */ + @Override + public void run() { + // 获取当前任务执行锁 最多持有30s自动释放 + Integer jobId = jobEntity.getJobId(); + RLock rLock = redissonClient.getLock(EXECUTE_LOCK + jobId); + try { + boolean lock = rLock.tryLock(0, 30, TimeUnit.SECONDS); + if (!lock) { + return; + } + // 查询上次执行时间 校验执行间隔 + SmartJobEntity dbJobEntity = jobRepository.getJobDao().selectById(jobId); + if (null == dbJobEntity) { + return; + } + LocalDateTime lastExecuteTime = dbJobEntity.getLastExecuteTime(); + if (null != lastExecuteTime) { + LocalDateTime nextTime = SmartJobUtil.queryNextTimeFromLast(jobEntity.getTriggerType(), jobEntity.getTriggerValue(), lastExecuteTime, 1).get(0); + if (LocalDateTime.now().isBefore(nextTime)) { + return; + } + } + // 执行任务 + SmartJobLogEntity logEntity = this.execute(SmartJobConst.SYSTEM_NAME); + log.info("==== SmartJob ==== execute job->{},time-millis->{}ms", jobEntity.getJobName(), logEntity.getExecuteTimeMillis()); + } catch (Throwable t) { + log.error("==== SmartJob ==== execute err:", t); + } finally { + if (rLock.isHeldByCurrentThread()) { + rLock.unlock(); + } + } + } + + /** + * 执行任务 + * + * @param executorName + */ + public SmartJobLogEntity execute(String executorName) { + // 保存执行记录 + LocalDateTime startTime = LocalDateTime.now(); + Long logId = this.saveLogBeforeExecute(jobEntity, executorName, startTime); + + // 执行计时 + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + // 执行任务 + boolean successFlag = true; + String executeResult; + try { + executeResult = jobInterface.run(jobEntity.getParam()); + stopWatch.stop(); + } catch (Throwable t) { + stopWatch.stop(); + successFlag = false; + // ps:异常信息不大于数据库字段长度限制 + executeResult = ExceptionUtil.stacktraceToString(t, 1800); + log.error("==== SmartJob ==== execute err:", t); + } + + // 更新执行记录 + SmartJobLogEntity logEntity = new SmartJobLogEntity(); + logEntity.setLogId(logId); + logEntity.setSuccessFlag(successFlag); + long totalTimeMillis = stopWatch.getTotalTimeMillis(); + logEntity.setExecuteTimeMillis(totalTimeMillis); + logEntity.setExecuteEndTime(startTime.plus(totalTimeMillis, ChronoUnit.MILLIS)); + logEntity.setExecuteResult(executeResult); + jobRepository.getJobLogDao().updateById(logEntity); + return logEntity; + } + + /** + * 执行前 保存执行记录 + * + * @param jobEntity + * @param executorName + * @param executeTime + * @return 返回执行记录id + */ + private Long saveLogBeforeExecute(SmartJobEntity jobEntity, + String executorName, + LocalDateTime executeTime) { + Integer jobId = jobEntity.getJobId(); + // 保存执行记录 + SmartJobLogEntity logEntity = new SmartJobLogEntity(); + logEntity.setJobId(jobId); + logEntity.setJobName(jobEntity.getJobName()); + logEntity.setParam(jobEntity.getParam()); + logEntity.setSuccessFlag(true); + // 执行开始时间 + logEntity.setExecuteStartTime(executeTime); + logEntity.setExecuteEndTime(executeTime); + logEntity.setExecuteTimeMillis(0L); + logEntity.setCreateName(executorName); + logEntity.setIp(SmartIpUtil.getLocalFirstIp()); + logEntity.setProcessId(SmartJobUtil.getProcessId()); + logEntity.setProgramPath(SmartJobUtil.getProgramPath()); + + // 更新最后执行时间 + SmartJobEntity updateJobEntity = new SmartJobEntity(); + updateJobEntity.setJobId(jobId); + updateJobEntity.setLastExecuteTime(executeTime); + jobRepository.saveLog(logEntity, updateJobEntity); + return logEntity.getLogId(); + } + + /** + * 查询 当前任务信息 + * + * @return + */ + public SmartJobEntity getJob() { + return jobEntity; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobLauncher.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobLauncher.java new file mode 100644 index 0000000..6b51751 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobLauncher.java @@ -0,0 +1,153 @@ +package net.lab1024.sa.base.module.support.job.core; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.job.config.SmartJobConfig; +import net.lab1024.sa.base.module.support.job.constant.SmartJobConst; +import net.lab1024.sa.base.module.support.job.constant.SmartJobUtil; +import net.lab1024.sa.base.module.support.job.repository.SmartJobRepository; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import org.redisson.api.RedissonClient; +import org.springframework.util.CollectionUtils; + +import javax.annotation.PreDestroy; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 定时任务 作业启动类 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Slf4j +public class SmartJobLauncher { + + private final SmartJobRepository jobRepository; + + private final List jobInterfaceList; + + private final RedissonClient redissonClient; + + public SmartJobLauncher(SmartJobConfig jobConfig, + SmartJobRepository jobRepository, + List jobInterfaceList, + RedissonClient redissonClient) { + this.jobRepository = jobRepository; + this.jobInterfaceList = jobInterfaceList; + this.redissonClient = redissonClient; + + // init job scheduler + SmartJobScheduler.init(jobConfig); + + // 任务自动检测配置 固定1个线程 + Integer initDelay = jobConfig.getInitDelay(); + Boolean refreshEnabled = jobConfig.getDbRefreshEnabled(); + Integer refreshInterval = jobConfig.getDbRefreshInterval(); + + ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("SmartJobLauncher-%d").build(); + ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, factory); + Runnable launcherRunnable = () -> { + try { + // 查询所有任务 + List smartJobList = this.queryJob(); + this.startOrRefreshJob(smartJobList); + } catch (Throwable t) { + log.error("SmartJob Error:", t); + } + // 只在启动时 执行一次 + if (!refreshEnabled) { + executor.shutdown(); + } + }; + executor.scheduleWithFixedDelay(launcherRunnable, initDelay, refreshInterval, TimeUnit.SECONDS); + + // 打印信息 + String refreshDesc = refreshEnabled ? "开启|检测间隔" + refreshInterval + "秒" : "关闭"; + String format = String.format(SmartJobConst.LOGO, jobConfig.getCorePoolSize(), initDelay, refreshDesc); + SmartJobUtil.printInfo(format); + } + + /** + * 查询数据库 + * 启动/刷新任务 + */ + public void startOrRefreshJob(List smartJobList) { + // 查询任务配置 + if (CollectionUtils.isEmpty(smartJobList) || CollectionUtils.isEmpty(jobInterfaceList)) { + log.info("==== SmartJob ==== job list empty"); + return; + } + + // 任务实现类 + Map jobImplMap = jobInterfaceList.stream().collect(Collectors.toMap(SmartJob::getClassName, Function.identity())); + for (SmartJobEntity jobEntity : smartJobList) { + // 任务是否存在 判断是否需要更新 + Integer jobId = jobEntity.getJobId(); + SmartJobEntity oldJobEntity = SmartJobScheduler.getJobInfo(jobId); + if (null != oldJobEntity) { + // 不需要更新 + if (!isNeedUpdate(oldJobEntity, jobEntity)) { + continue; + } + // 需要更新 移除原任务 + SmartJobScheduler.removeJob(jobId); + } + // 任务未开启 + if (!jobEntity.getEnabledFlag()) { + continue; + } + // 任务删除 + if (jobEntity.getDeletedFlag()) { + continue; + } + // 查找任务实现类 + SmartJob jobImpl = jobImplMap.get(jobEntity.getJobClass()); + if (null == jobImpl) { + continue; + } + // 添加任务 + SmartJobExecutor jobExecute = new SmartJobExecutor(jobEntity, jobRepository, jobImpl, redissonClient); + SmartJobScheduler.addJob(jobExecute); + } + List runjJobList = SmartJobScheduler.getJobInfo(); + List jobNameList = runjJobList.stream().map(SmartJobEntity::getJobName).collect(Collectors.toList()); + log.info("==== SmartJob ==== start/refresh job num:{}->{}", runjJobList.size(), jobNameList); + } + + /** + * 查询全部任务 + * + * @return + */ + private List queryJob() { + return jobRepository.getJobDao().selectList(null); + } + + /** + * 手动判断 任务配置 是否需要更新 + * 新增字段的话 在这个方法里增加判断 + * + * @return + */ + private static boolean isNeedUpdate(SmartJobEntity oldJob, SmartJobEntity newJob) { + // cron为空时 fixedDelay 才有意义 + return !Objects.equals(oldJob.getEnabledFlag(), newJob.getEnabledFlag()) + || !Objects.equals(oldJob.getDeletedFlag(), newJob.getDeletedFlag()) + || !Objects.equals(oldJob.getTriggerType(), newJob.getTriggerType()) + || !Objects.equals(oldJob.getTriggerValue(), newJob.getTriggerValue()) + || !Objects.equals(oldJob.getJobClass(), newJob.getJobClass()); + } + + @PreDestroy + public void destroy() { + SmartJobScheduler.destroy(); + log.info("==== SmartJob ==== destroy job"); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobScheduler.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobScheduler.java new file mode 100644 index 0000000..6706736 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/core/SmartJobScheduler.java @@ -0,0 +1,178 @@ +package net.lab1024.sa.base.module.support.job.core; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.job.config.SmartJobConfig; +import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum; +import net.lab1024.sa.base.module.support.job.constant.SmartJobUtil; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.scheduling.support.PeriodicTrigger; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * 定时任务 调度管理 + * + * @author huke + * @date 2024/6/22 21:30 + */ +@Slf4j +public class SmartJobScheduler { + + /** + * Spring线程池任务调度器 + */ + private static ThreadPoolTaskScheduler TASK_SCHEDULER; + + /** + * 定时任务 map + */ + private static Map>> JOB_FUTURE_MAP; + + private SmartJobScheduler() { + + } + + /** + * 初始化任务调度配置 + */ + public static void init(SmartJobConfig config) { + TASK_SCHEDULER = new ThreadPoolTaskScheduler(); + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("SmartJobExecutor-%d").build(); + TASK_SCHEDULER.setThreadFactory(threadFactory); + TASK_SCHEDULER.setPoolSize(config.getCorePoolSize()); + // 线程池在关闭时会等待所有任务完成 + TASK_SCHEDULER.setWaitForTasksToCompleteOnShutdown(true); + // 在调用shutdown方法后,等待任务完成的最长时间 + TASK_SCHEDULER.setAwaitTerminationSeconds(10); + // 错误处理 + TASK_SCHEDULER.setErrorHandler((t) -> log.error("SmartJobExecute Err:", t)); + // 当一个任务在被调度执行前被取消时,是否应该从线程池的任务队列中移除 + TASK_SCHEDULER.setRemoveOnCancelPolicy(true); + TASK_SCHEDULER.initialize(); + + JOB_FUTURE_MAP = new ConcurrentHashMap<>(); + } + + /** + * 获取任务执行对象 + * + * @param jobId + * @return + */ + public static ScheduledFuture getJobFuture(Integer jobId) { + Pair> pair = JOB_FUTURE_MAP.get(jobId); + if (null == pair) { + return null; + } + return pair.getRight(); + } + + /** + * 获取当前所有执行任务 + * + * @return + */ + public static List getJobInfo() { + return JOB_FUTURE_MAP.values().stream().map(Pair::getLeft).collect(Collectors.toList()); + } + + /** + * 获取任务执行实体类 + * + * @param jobId + * @return + */ + public static SmartJobEntity getJobInfo(Integer jobId) { + Pair> pair = JOB_FUTURE_MAP.get(jobId); + if (null == pair) { + return null; + } + return pair.getLeft(); + } + + /** + * 添加任务 + * + * @param jobExecute + * @return + */ + public static void addJob(SmartJobExecutor jobExecute) { + // 任务是否存在 + SmartJobEntity jobEntity = jobExecute.getJob(); + Integer jobId = jobEntity.getJobId(); + if (JOB_FUTURE_MAP.containsKey(jobId)) { + // 移除任务 + removeJob(jobId); + } + // 任务触发类型 + Trigger trigger = null; + String triggerType = jobEntity.getTriggerType(); + String triggerValue = jobEntity.getTriggerValue(); + // 优先 cron 表达式 + if (SmartJobTriggerTypeEnum.CRON.equalsValue(triggerType)) { + trigger = new CronTrigger(triggerValue); + } else if (SmartJobTriggerTypeEnum.FIXED_DELAY.equalsValue(triggerType)) { + trigger = new PeriodicTrigger(SmartJobUtil.getFixedDelayVal(triggerValue), TimeUnit.SECONDS); + } + String jobName = jobEntity.getJobName(); + if (null == trigger) { + log.error("==== SmartJob ==== trigger-value not null {}", jobName); + return; + } + // 执行任务 + ScheduledFuture schedule = TASK_SCHEDULER.schedule(jobExecute, trigger); + JOB_FUTURE_MAP.put(jobId, Pair.of(jobEntity, schedule)); + log.info("==== SmartJob ==== add job:{}", jobName); + } + + /** + * 移除任务 + * 等待任务执行完成后移除 + * + * @param jobId + */ + public static void removeJob(Integer jobId) { + ScheduledFuture jobFuture = getJobFuture(jobId); + if (null == jobFuture) { + return; + } + // 结束任务 + stopJob(jobFuture); + JOB_FUTURE_MAP.remove(jobId); + log.info("==== SmartJob ==== remove job:{}", jobId); + } + + /** + * 停止所有定时任务 + */ + public static void destroy() { + // 启动一个有序的关闭过程,在这个过程中,不再接受新的任务提交,但已提交的任务(包括正在执行的和队列中等待的)会被允许执行完成。 + TASK_SCHEDULER.destroy(); + JOB_FUTURE_MAP.clear(); + } + + /** + * 结束任务 + * 如果任务还没有开始执行,会直接被取消。 + * 如果任务已经开始执行,此时不会中断执行中的线程,任务会执行完成再被取消 + * + * @param scheduledFuture + */ + private static void stopJob(ScheduledFuture scheduledFuture) { + if (null == scheduledFuture || scheduledFuture.isCancelled()) { + return; + } + scheduledFuture.cancel(false); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobDao.java new file mode 100644 index 0000000..028f87c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobDao.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.base.module.support.job.repository; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.job.api.domain.SmartJobQueryForm; +import net.lab1024.sa.base.module.support.job.api.domain.SmartJobVO; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 定时任务 dao + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Mapper +public interface SmartJobDao extends BaseMapper { + + /** + * 定时任务-分页查询 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") SmartJobQueryForm queryForm); + + /** + * 假删除 + * + * @param jobId + * @return + */ + void updateDeletedFlag(@Param("jobId") Integer jobId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据 任务class 查找 + * + * @param jobClass + * @return + */ + SmartJobEntity selectByJobClass(@Param("jobClass") String jobClass); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobLogDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobLogDao.java new file mode 100644 index 0000000..b3b6a3d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobLogDao.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.job.repository; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.job.api.domain.SmartJobLogQueryForm; +import net.lab1024.sa.base.module.support.job.api.domain.SmartJobLogVO; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 定时任务-执行记录 dao + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Mapper +public interface SmartJobLogDao extends BaseMapper { + + /** + * 定时任务-执行记录-分页查询 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") SmartJobLogQueryForm queryForm); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobRepository.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobRepository.java new file mode 100644 index 0000000..f8d1773 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/SmartJobRepository.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.module.support.job.repository; + +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobEntity; +import net.lab1024.sa.base.module.support.job.repository.domain.SmartJobLogEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * job 持久化业务 + * + * @author huke + * @date 2024/6/22 22:28 + */ +@Service +public class SmartJobRepository { + + @Autowired + private SmartJobDao jobDao; + + @Autowired + private SmartJobLogDao jobLogDao; + + public SmartJobDao getJobDao() { + return jobDao; + } + + public SmartJobLogDao getJobLogDao() { + return jobLogDao; + } + + /** + * 保存执行记录 + * + * @param logEntity + * @param jobEntity + */ + @Transactional(rollbackFor = Throwable.class) + public void saveLog(SmartJobLogEntity logEntity, SmartJobEntity jobEntity) { + jobLogDao.insert(logEntity); + + jobEntity.setLastExecuteLogId(logEntity.getLogId()); + jobDao.updateById(jobEntity); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobEntity.java new file mode 100644 index 0000000..890bc63 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobEntity.java @@ -0,0 +1,89 @@ +package net.lab1024.sa.base.module.support.job.repository.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum; + +import java.time.LocalDateTime; + +/** + * 定时任务 实体类 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Data +@TableName("t_smart_job") +public class SmartJobEntity { + + /** + * 任务id + */ + @TableId(type = IdType.AUTO) + private Integer jobId; + + /** + * 任务名称 + */ + private String jobName; + + /** + * 执行类 + */ + private String jobClass; + + /** + * 触发类型 + * + * @see SmartJobTriggerTypeEnum + */ + private String triggerType; + + /** + * 触发配置 + */ + private String triggerValue; + + /** + * 定时任务参数 可选 + */ + private String param; + + /** + * 是否启用 + */ + private Boolean enabledFlag; + + /** + * 最后一执行时间 + */ + private LocalDateTime lastExecuteTime; + + /** + * 最后一次执行记录id + */ + private Long lastExecuteLogId; + + /** + * 备注描述 可选 + */ + private String remark; + + /** + * 排序 + */ + private Integer sort; + + /** + * 是否删除 + */ + private Boolean deletedFlag; + + private String updateName; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobLogEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobLogEntity.java new file mode 100644 index 0000000..95c1d49 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobLogEntity.java @@ -0,0 +1,81 @@ +package net.lab1024.sa.base.module.support.job.repository.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 定时任务 执行记录 实体类 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Data +@TableName("t_smart_job_log") +public class SmartJobLogEntity { + + @TableId(type = IdType.AUTO) + private Long logId; + + /** + * 任务id + */ + private Integer jobId; + + /** + * 任务名称 + */ + private String jobName; + + /** + * 定时任务参数 可选 + */ + private String param; + + /** + * 执行结果 是否成功 + */ + private Boolean successFlag; + + /** + * 开始执行时间 + */ + private LocalDateTime executeStartTime; + + /** + * 执行时长-毫秒 + */ + private Long executeTimeMillis; + + /** + * 执行结束时间 + */ + private LocalDateTime executeEndTime; + + /** + * 执行结果 描述 可选 + */ + private String executeResult; + + /** + * ip + */ + private String ip; + + /** + * 进程id + */ + private String processId; + + /** + * 程序目录 + */ + private String programPath; + + private String createName; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/SmartJobSample1.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/SmartJobSample1.java new file mode 100644 index 0000000..7036915 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/SmartJobSample1.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.base.module.support.job.sample; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.job.core.SmartJob; +import org.springframework.stereotype.Service; + +/** + * 定时任务 示例1 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Slf4j +@Service +public class SmartJobSample1 implements SmartJob { + + /** + * 定时任务示例 + * + * @param param 可选参数 任务不需要时不用管 + * @return + */ + @Override + public String run(String param) { + // 写点什么业务逻辑 + return "执行完毕,随便说点什么吧"; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/SmartJobSample2.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/SmartJobSample2.java new file mode 100644 index 0000000..18d9a21 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/SmartJobSample2.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.base.module.support.job.sample; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.config.ConfigDao; +import net.lab1024.sa.base.module.support.config.domain.ConfigEntity; +import net.lab1024.sa.base.module.support.job.core.SmartJob; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 定时任务 示例2 + * + * @author huke + * @date 2024/6/17 21:30 + */ +@Slf4j +@Service +public class SmartJobSample2 implements SmartJob { + + @Autowired + private ConfigDao configDao; + + /** + * 定时任务示例 + * 需要事务时 添加 @Transactional 注解 + * + * @param param 可选参数 任务不需要时不用管 + * @return + */ + @Transactional(rollbackFor = Throwable.class) + @Override + public String run(String param) { + // 随便更新点什么东西 + ConfigEntity configEntity = new ConfigEntity(); + configEntity.setConfigId(1L); + configEntity.setRemark(param); + configDao.updateById(configEntity); + + configEntity = new ConfigEntity(); + configEntity.setConfigId(2L); + configEntity.setRemark("SmartJob Sample2 update"); + configDao.updateById(configEntity); + + return "执行成功,本次处理数据1条"; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/package-info.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/package-info.java new file mode 100644 index 0000000..d72e5a7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/job/sample/package-info.java @@ -0,0 +1,5 @@ +/** + * 定时任务 示例包 + * 可以删除 + */ +package net.lab1024.sa.base.module.support.job.sample; \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogDao.java new file mode 100644 index 0000000..b0509f0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogDao.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.module.support.loginlog; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogEntity; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogQueryForm; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface LoginLogDao extends BaseMapper { + + /** + * 分页查询 + * + * @param page + * @param queryForm + * @return LoginLogVO + */ + List queryByPage(Page page, @Param("query") LoginLogQueryForm queryForm); + + /** + * 查询上一个登录记录 + * + * @param userId + * @param userType + * @return LoginLogVO + */ + LoginLogVO queryLastByUserId(@Param("userId") Long userId,@Param("userType") Integer userType, @Param("loginLogResult")Integer loginLogResult); + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogResultEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogResultEnum.java new file mode 100644 index 0000000..e867a2c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogResultEnum.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.loginlog; + +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 登录类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public enum LoginLogResultEnum implements BaseEnum { + + LOGIN_SUCCESS(0, "登录成功"), + LOGIN_FAIL(1, "登录失败"), + LOGIN_OUT(2, "退出登录"); + + private Integer type; + private String desc; + + LoginLogResultEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + @Override + public Integer getValue() { + return type; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogService.java new file mode 100644 index 0000000..b7dfcd7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/LoginLogService.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.base.module.support.loginlog; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogEntity; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogQueryForm; +import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogVO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +@Slf4j +public class LoginLogService { + + @Resource + private LoginLogDao loginLogDao; + + /** + * @author 卓大 + * @description 分页查询 + */ + public ResponseDTO> queryByPage(LoginLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List logList = loginLogDao.queryByPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, logList); + return ResponseDTO.ok(pageResult); + } + + /** + * @author 卓大 + * @description 添加 + */ + public void log(LoginLogEntity loginLogEntity) { + try { + loginLogDao.insert(loginLogEntity); + } catch (Throwable e) { + log.error(e.getMessage(), e); + } + } + + + /** + * 查询上一个登录记录 + * + * @author 卓大 + * @description 查询上一个登录记录 + */ + public LoginLogVO queryLastByUserId(Long userId, UserTypeEnum userTypeEnum, LoginLogResultEnum loginLogResultEnum) { + return loginLogDao.queryLastByUserId(userId,userTypeEnum.getValue(), loginLogResultEnum.getValue()); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity.java new file mode 100644 index 0000000..2ef5dba --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.base.module.support.loginlog.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@TableName("t_login_log") +@Data +@Builder +public class LoginLogEntity { + + @TableId(type = IdType.AUTO) + private Long loginLogId; + + /** + * 用户id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 用户名 + */ + private String userName; + + /** + * 登录ip + */ + private String loginIp; + + /** + * 登录ip地区 + */ + private String loginIpRegion; + + /** + * user-agent + */ + private String userAgent; + + /** + * 备注 + */ + private String remark; + + /** + * 登录设备 + */ + private String loginDevice; + + /** + * 登录类型 + */ + private Integer loginResult; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogQueryForm.java new file mode 100644 index 0000000..7af0dbe --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogQueryForm.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.loginlog.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +/** + * 登录查询日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class LoginLogQueryForm extends PageParam { + + @Schema(description = "用户ID") + private Long userId; + + @Schema(description = "用户类型") + private Integer userType; + + @Schema(description = "开始日期") + private String startDate; + + @Schema(description = "结束日期") + private String endDate; + + @Schema(description = "用户名称") + private String userName; + + @Schema(description = "ip") + private String ip; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogVO.java new file mode 100644 index 0000000..205a7fb --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogVO.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.base.module.support.loginlog.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.loginlog.LoginLogResultEnum; + +import java.time.LocalDateTime; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class LoginLogVO { + + private Long loginLogId; + + @Schema(description = "用户id") + private Long userId; + + @SchemaEnum(value = UserTypeEnum.class, desc = "用户类型") + private Integer userType; + + @Schema(description = "用户名") + private String userName; + + @Schema(description = "登录ip") + private String loginIp; + + @Schema(description = "登录ip地区") + private String loginIpRegion; + + @Schema(description = "user-agent") + private String userAgent; + + @Schema(description = "remark") + private String remark; + + @SchemaEnum(LoginLogResultEnum.class) + private Integer loginResult; + + private String loginDevice; + + private LocalDateTime createTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/MailService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/MailService.java new file mode 100644 index 0000000..ada8f54 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/MailService.java @@ -0,0 +1,178 @@ +package net.lab1024.sa.base.module.support.mail; + + +import cn.hutool.core.util.IdUtil; +import freemarker.cache.StringTemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.Template; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.SystemEnvironment; +import net.lab1024.sa.base.module.support.mail.constant.MailTemplateCodeEnum; +import net.lab1024.sa.base.module.support.mail.constant.MailTemplateTypeEnum; +import net.lab1024.sa.base.module.support.mail.domain.MailTemplateEntity; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StringSubstitutor; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.File; +import java.io.StringWriter; +import java.io.Writer; +import java.util.List; +import java.util.Map; + +/** + * + * 发送邮件:
+ * 1、支持直接发送
+ * 2、支持使用邮件模板发送 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/8/5 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ +@Slf4j +@Component +public class MailService { + + @Resource + private JavaMailSender javaMailSender; + + @Resource + private MailTemplateDao mailTemplateDao; + + @Resource + private SystemEnvironment systemEnvironment; + + @Value("${spring.mail.username}") + private String clientMail; + + + /** + * 使用模板发送邮件 + */ + public ResponseDTO sendMail(MailTemplateCodeEnum templateCode, Map templateParamsMap, List receiverUserList, List fileList) { + + MailTemplateEntity mailTemplateEntity = mailTemplateDao.selectById(templateCode.name().toLowerCase()); + if (mailTemplateEntity == null) { + return ResponseDTO.userErrorParam("模版不存在"); + } + + if (mailTemplateEntity.getDisableFlag()) { + return ResponseDTO.userErrorParam("模版已禁用,无法发送"); + } + + String content = null; + if (MailTemplateTypeEnum.FREEMARKER.name().equalsIgnoreCase(mailTemplateEntity.getTemplateType().trim())) { + content = freemarkerResolverContent(mailTemplateEntity.getTemplateContent(), templateParamsMap); + } else if (MailTemplateTypeEnum.STRING.name().equalsIgnoreCase(mailTemplateEntity.getTemplateType().trim())) { + content = stringResolverContent(mailTemplateEntity.getTemplateContent(), templateParamsMap); + } else { + return ResponseDTO.userErrorParam("模版类型不存在"); + } + + try { + + this.sendMail(mailTemplateEntity.getTemplateSubject(), content, fileList, receiverUserList, true); + + } catch (Throwable e) { + log.error("邮件发送失败", e); + return ResponseDTO.userErrorParam("邮件发送失败"); + } + return ResponseDTO.ok(); + } + + /** + * 使用模板发送邮件 + */ + public ResponseDTO sendMail(MailTemplateCodeEnum templateCode, Map templateParamsMap, List receiverUserList) { + return this.sendMail(templateCode, templateParamsMap, receiverUserList, null); + } + + + /** + * 发送邮件 + * + * @param subject 主题 + * @param content 内容 + * @param fileList 文件 + * @param receiverUserList 接收方 + * @throws MessagingException + */ + public void sendMail(String subject, String content, List fileList, List receiverUserList, boolean isHtml) throws MessagingException { + + if (CollectionUtils.isEmpty(receiverUserList)) { + throw new RuntimeException("接收方不能为空"); + } + + if (StringUtils.isBlank(content)) { + throw new RuntimeException("邮件内容不能为空"); + } + + if (!systemEnvironment.isProd()) { + subject = "(测试)" + subject; + } + + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + + //是否为多文件上传 + boolean multiparty = !CollectionUtils.isEmpty(fileList); + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, multiparty); + helper.setFrom(clientMail); + helper.setTo(receiverUserList.toArray(new String[0])); + helper.setSubject(subject); + //发送html格式 + helper.setText(content, isHtml); + + //附件 + if (multiparty) { + for (File file : fileList) { + helper.addAttachment(file.getName(), file); + } + } + javaMailSender.send(mimeMessage); + } + + /** + * 使用字符串生成最终内容 + */ + private String stringResolverContent(String stringTemplate, Map templateParamsMap) { + StringSubstitutor stringSubstitutor = new StringSubstitutor(templateParamsMap); + String contractHtml = stringSubstitutor.replace(stringTemplate); + Document doc = Jsoup.parse(contractHtml); + doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml); + return doc.outerHtml(); + } + + + /** + * 使用 freemarker 生成最终内容 + */ + private String freemarkerResolverContent(String htmlTemplate, Map templateParamsMap) { + Configuration configuration = new Configuration(Configuration.VERSION_2_3_23); + StringTemplateLoader stringLoader = new StringTemplateLoader(); + String templateName = IdUtil.fastSimpleUUID(); + stringLoader.putTemplate(templateName, htmlTemplate); + configuration.setTemplateLoader(stringLoader); + try { + Template template = configuration.getTemplate(templateName, "utf-8"); + Writer out = new StringWriter(2048); + template.process(templateParamsMap, out); + return out.toString(); + } catch (Throwable e) { + log.error("freemarkerResolverContent error: ", e); + } + return ""; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/MailTemplateDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/MailTemplateDao.java new file mode 100644 index 0000000..ecc6b07 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/MailTemplateDao.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.base.module.support.mail; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.mail.domain.MailTemplateEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 邮件模板 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/8/5 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ +@Mapper +public interface MailTemplateDao extends BaseMapper { + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/constant/MailTemplateCodeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/constant/MailTemplateCodeEnum.java new file mode 100644 index 0000000..9eab6ca --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/constant/MailTemplateCodeEnum.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.base.module.support.mail.constant; + +/** + * 模版编码 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/8/5 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ +public enum MailTemplateCodeEnum { + + /** + * 登录验证码 + */ + LOGIN_VERIFICATION_CODE + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/constant/MailTemplateTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/constant/MailTemplateTypeEnum.java new file mode 100644 index 0000000..f26ef24 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/constant/MailTemplateTypeEnum.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.base.module.support.mail.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 邮件模板类型 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/8/5 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ + +@Getter +@AllArgsConstructor +public enum MailTemplateTypeEnum implements BaseEnum { + + STRING("string", "字符串替代器"), + + FREEMARKER("freemarker", "freemarker模板引擎"); + + private String value; + + private String desc; + + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/domain/MailTemplateEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/domain/MailTemplateEntity.java new file mode 100644 index 0000000..8f16163 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/mail/domain/MailTemplateEntity.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.base.module.support.mail.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * + * 邮件模板 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/8/5 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ +@Data +@TableName("t_mail_template") +public class MailTemplateEntity { + + @TableId(type = IdType.NONE) + private String templateCode; + + /** + * 主题 + */ + private String templateSubject; + + /** + * 模板类型 + */ + private String templateType; + + /** + * 模板内容 + */ + private String templateContent; + + /** + * 禁用标识 + */ + private Boolean disableFlag; + + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/constant/MessageTemplateEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/constant/MessageTemplateEnum.java new file mode 100644 index 0000000..d9c6785 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/constant/MessageTemplateEnum.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.message.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 消息模板类型 + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Getter +@AllArgsConstructor +public enum MessageTemplateEnum implements BaseEnum { + + + + ORDER_AUDIT(1000, "订单审批", MessageTypeEnum.ORDER, "您有一个订单等待审批,订单号【${orderNumber}】"), + + ; + + private final Integer value; + + private final String desc; + + private final MessageTypeEnum messageTypeEnum; + + private final String content; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/constant/MessageTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/constant/MessageTypeEnum.java new file mode 100644 index 0000000..b94cb10 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/constant/MessageTypeEnum.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.base.module.support.message.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + + +/** + * 消息类型 + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Getter +@AllArgsConstructor +public enum MessageTypeEnum implements BaseEnum { + + MAIL(1, "站内信"), + + ORDER(2, "订单"), + ; + + private final Integer value; + + private final String desc; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/controller/MessageController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/controller/MessageController.java new file mode 100644 index 0000000..3a1548f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/controller/MessageController.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.base.module.support.message.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.message.domain.MessageQueryForm; +import net.lab1024.sa.base.module.support.message.domain.MessageVO; +import net.lab1024.sa.base.module.support.message.service.MessageService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 消息 + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.MESSAGE) +public class MessageController extends SupportBaseController { + + @Resource + private MessageService messageService; + + @Operation(summary = "分页查询我的消息 @luoyi") + @PostMapping("/message/queryMyMessage") + public ResponseDTO> query(@RequestBody @Valid MessageQueryForm queryForm) { + RequestUser user = SmartRequestUtil.getRequestUser(); + if(user == null){ + return ResponseDTO.userErrorParam("用户未登录"); + } + + queryForm.setSearchCount(false); + queryForm.setReceiverUserId(user.getUserId()); + queryForm.setReceiverUserType(user.getUserType().getValue()); + return ResponseDTO.ok(messageService.query(queryForm)); + } + + @Operation(summary = "查询未读消息数量 @luoyi") + @GetMapping("/message/getUnreadCount") + public ResponseDTO getUnreadCount() { + RequestUser user = SmartRequestUtil.getRequestUser(); + if(user == null){ + return ResponseDTO.userErrorParam("用户未登录"); + } + return ResponseDTO.ok(messageService.getUnreadCount(user.getUserType(), user.getUserId())); + } + + @Operation(summary = "更新已读 @luoyi") + @GetMapping("/message/read/{messageId}") + public ResponseDTO updateReadFlag(@PathVariable Long messageId) { + RequestUser user = SmartRequestUtil.getRequestUser(); + if(user == null){ + return ResponseDTO.userErrorParam("用户未登录"); + } + + messageService.updateReadFlag(messageId, user.getUserType(), user.getUserId()); + return ResponseDTO.ok(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/dao/MessageDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/dao/MessageDao.java new file mode 100644 index 0000000..01389e0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/dao/MessageDao.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.module.support.message.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.message.domain.MessageEntity; +import net.lab1024.sa.base.module.support.message.domain.MessageQueryForm; +import net.lab1024.sa.base.module.support.message.domain.MessageVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 消息 接受者类型枚举 + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Mapper +public interface MessageDao extends BaseMapper { + + /** + * 分页查询消息 + * + */ + List query(Page page, @Param("query") MessageQueryForm queryForm); + + /** + * 更新已读状态 + */ + Integer updateReadFlag(@Param("messageId") Long messageId, + @Param("receiverUserType") Integer receiverUserType, + @Param("receiverUserId") Long receiverUserId, + @Param("readFlag") Boolean readFlag); + + /** + * 查询未读消息数 + */ + Long getUnreadCount( @Param("receiverUserType") Integer receiverUserType, + @Param("receiverUserId") Long receiverUserId); + + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageEntity.java new file mode 100644 index 0000000..673ed69 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageEntity.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.base.module.support.message.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.base.module.support.message.constant.MessageTypeEnum; + +import java.time.LocalDateTime; + +/** + * 消息实体 + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Data +@TableName("t_message") +public class MessageEntity { + + @TableId(type = IdType.AUTO) + private Long messageId; + + /** + * 消息类型 + * + * @see MessageTypeEnum + */ + private Integer messageType; + /** + * 接收者类型 + * + * @see net.lab1024.sa.base.common.enumeration.UserTypeEnum + */ + private Integer receiverUserType; + + /** + * 接收者id + */ + private Long receiverUserId; + + /** + * 相关业务id + */ + private String dataId; + + /** + * 消息标题 + */ + private String title; + + /** + * 消息内容 + */ + private String content; + + /** + * 是否已读 + */ + private Boolean readFlag; + + /** + * 已读时间 + */ + private LocalDateTime readTime; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageQueryForm.java new file mode 100644 index 0000000..fe80d70 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageQueryForm.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.base.module.support.message.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.base.module.support.message.constant.MessageTypeEnum; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * 消息查询form + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Data +public class MessageQueryForm extends PageParam { + + @Schema(description = "搜索词") + @Length(max = 50, message = "搜索词最多50字符") + private String searchWord; + + @SchemaEnum(value = MessageTypeEnum.class) + @CheckEnum(value = MessageTypeEnum.class, message = "消息类型") + private Integer messageType; + + @Schema(description = "是否已读") + private Boolean readFlag; + + @Schema(description = "查询开始时间") + private LocalDate startDate; + + @Schema(description = "查询结束时间") + private LocalDate endDate; + + @Schema(description = "接收人") + private Long receiverUserId; + + @Schema(description = "接收人类型") + private Integer receiverUserType; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageSendForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageSendForm.java new file mode 100644 index 0000000..fa08df1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageSendForm.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.base.module.support.message.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.message.constant.MessageTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +/** + * 消息发送form + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Data +public class MessageSendForm { + + @SchemaEnum(value = MessageTypeEnum.class, desc = "消息类型") + @NotNull(message = "消息类型不能为空") + private Integer messageType; + + @SchemaEnum(value = UserTypeEnum.class, desc = "接收者类型") + @NotNull(message = "接收者类型不能为空") + private Integer receiverUserType; + + @Schema(description = "接收者id") + @NotNull(message = "接收者id不能为空") + private Long receiverUserId; + + @Schema(description = "标题") + @NotBlank(message = "标题") + private String title; + + @Schema(description = "内容") + @NotBlank(message = "内容") + private String content; + + /** + * 相关业务id | 可选 + */ + private Object dataId; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageTemplateSendForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageTemplateSendForm.java new file mode 100644 index 0000000..2eb1b6a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageTemplateSendForm.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.base.module.support.message.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.module.support.message.constant.MessageTemplateEnum; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; +import java.util.Map; + +/** + * 消息发送form + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Data +public class MessageTemplateSendForm { + + @NotNull(message = "消息子类型不能为空") + private MessageTemplateEnum messageTemplateEnum; + + @NotNull(message = "接收者类型不能为空") + private UserTypeEnum receiverUserType; + + @NotNull(message = "接收者id不能为空") + private Long receiverUserId; + + @Schema(description = "接收者id") + @NotEmpty(message = "接收者id不能为空") + private List receiverUserIdList; + + /** + * 相关业务id | 可选 + * 用于跳转具体业务 + */ + private Object dataId; + + /** + * 消息参数 | 可选 + * 例:订单号:【{orderId}】{time}所提交的对账单被作废,请核实信息重新提交~ + * {orderId} {time} 就是消息的参数变量 + * 发送消息时 需要在map中放入k->orderId k->time + */ + private Map contentParam; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageVO.java new file mode 100644 index 0000000..eb7366f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/domain/MessageVO.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.base.module.support.message.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; +import net.lab1024.sa.base.module.support.message.constant.MessageTypeEnum; + +import java.time.LocalDateTime; + +/** + * 消息 + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Data +public class MessageVO { + + private Long messageId; + + @SchemaEnum(value = MessageTypeEnum.class) + private Integer messageType; + + @SchemaEnum(value = UserTypeEnum.class) + private Integer receiverUserType; + + @Schema(description = "接收者id") + private Long receiverUserId; + + @Schema(description = "相关业务id") + private String dataId; + + @Schema(description = "消息标题") + private String title; + + @Schema(description = "消息内容") + private String content; + + @Schema(description = "是否已读") + private Boolean readFlag; + + @Schema(description = "已读时间") + private LocalDateTime readTime; + + @Schema(description = "创建时间") + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/service/MessageManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/service/MessageManager.java new file mode 100644 index 0000000..e1e2419 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/service/MessageManager.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.base.module.support.message.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.base.module.support.message.dao.MessageDao; +import net.lab1024.sa.base.module.support.message.domain.MessageEntity; +import org.springframework.stereotype.Service; + +/** + * 消息manager + * + * @author luoyi + * @date 2024/06/22 20:20 + */ +@Service +public class MessageManager extends ServiceImpl { + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/service/MessageService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/service/MessageService.java new file mode 100644 index 0000000..1ea591d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/message/service/MessageService.java @@ -0,0 +1,118 @@ +package net.lab1024.sa.base.module.support.message.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.message.constant.MessageTemplateEnum; +import net.lab1024.sa.base.module.support.message.dao.MessageDao; +import net.lab1024.sa.base.module.support.message.domain.*; +import org.apache.commons.text.StringSubstitutor; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author luoyi + * @date 2024/6/27 12:14 上午 + */ +@Service +public class MessageService { + + @Resource + private MessageDao messageDao; + + @Resource + private MessageManager messageManager; + + /** + * 分页查询 消息 + */ + public PageResult query(MessageQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List messageVOList = messageDao.query(page, queryForm); + return SmartPageUtil.convert2PageResult(page, messageVOList); + } + + /** + * 查询未读消息数量 + */ + public Long getUnreadCount(UserTypeEnum userType, Long userId) { + return messageDao.getUnreadCount(userType.getValue(), userId); + } + + /** + * 更新已读状态 + */ + public void updateReadFlag(Long messageId, UserTypeEnum userType, Long receiverUserId) { + messageDao.updateReadFlag(messageId, userType.getValue(), receiverUserId, true); + } + + + /** + * 发送【模板消息】 + */ + public void sendTemplateMessage(MessageTemplateSendForm... sendTemplateForms) { + List sendFormList = Lists.newArrayList(); + for (MessageTemplateSendForm sendTemplateForm : sendTemplateForms) { + MessageTemplateEnum msgTemplateTypeEnum = sendTemplateForm.getMessageTemplateEnum(); + StringSubstitutor stringSubstitutor = new StringSubstitutor(sendTemplateForm.getContentParam()); + String content = stringSubstitutor.replace(msgTemplateTypeEnum.getContent()); + + MessageSendForm messageSendForm = new MessageSendForm(); + messageSendForm.setMessageType(msgTemplateTypeEnum.getMessageTypeEnum().getValue()); + messageSendForm.setReceiverUserType(sendTemplateForm.getReceiverUserType().getValue()); + messageSendForm.setReceiverUserId(sendTemplateForm.getReceiverUserId()); + messageSendForm.setTitle(msgTemplateTypeEnum.getDesc()); + messageSendForm.setContent(content); + messageSendForm.setDataId(sendTemplateForm.getDataId()); + sendFormList.add(messageSendForm); + + } + this.sendMessage(sendFormList); + } + + /** + * 发送消息 + */ + public void sendMessage(MessageSendForm... sendForms) { + this.sendMessage(Lists.newArrayList(sendForms)); + } + + /** + * 批量发送通知消息 + */ + public void sendMessage(List sendList) { + for (MessageSendForm sendDTO : sendList) { + String verify = SmartBeanUtil.verify(sendDTO); + if (null != verify) { + throw new RuntimeException("send msg error: " + verify); + } + } + List messageEntityList = sendList.stream().map(e -> { + MessageEntity messageEntity = new MessageEntity(); + messageEntity.setMessageType(e.getMessageType()); + messageEntity.setReceiverUserType(e.getReceiverUserType()); + messageEntity.setReceiverUserId(e.getReceiverUserId()); + messageEntity.setDataId(String.valueOf(e.getDataId())); + messageEntity.setTitle(e.getTitle()); + messageEntity.setContent(e.getContent()); + return messageEntity; + }).collect(Collectors.toList()); + messageManager.saveBatch(messageEntityList); + } + + // 删除消息 + public ResponseDTO delete(Long messageId) { + if(messageId == null){ + return ResponseDTO.userErrorParam(); + } + messageDao.deleteById(messageId); + return ResponseDTO.ok(); + } +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/OperateLogDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/OperateLogDao.java new file mode 100644 index 0000000..cdf520a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/OperateLogDao.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.base.module.support.operatelog; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogEntity; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 操作日志 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface OperateLogDao extends BaseMapper { + + /** + * 分页查询 + * @param page + * @param queryForm + * @return UserOperateLogEntity + */ + List queryByPage(Page page, @Param("query") OperateLogQueryForm queryForm); + + + /** + * 批量删除 + * + * @param idList + * @return + */ + void deleteByIds(@Param("idList") List idList); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/OperateLogService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/OperateLogService.java new file mode 100644 index 0000000..a621b77 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/OperateLogService.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.base.module.support.operatelog; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogEntity; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogQueryForm; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogVO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 操作日志 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class OperateLogService { + + @Resource + private OperateLogDao operateLogDao; + + /** + * @author 罗伊 + * @description 分页查询 + */ + public ResponseDTO> queryByPage(OperateLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List logEntityList = operateLogDao.queryByPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, logEntityList, OperateLogVO.class); + return ResponseDTO.ok(pageResult); + } + + + /** + * 查询详情 + * @param operateLogId + * @return + */ + public ResponseDTO detail(Long operateLogId) { + OperateLogEntity operateLogEntity = operateLogDao.selectById(operateLogId); + if(operateLogEntity == null){ + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + OperateLogVO operateLogVO = SmartBeanUtil.copy(operateLogEntity, OperateLogVO.class); + return ResponseDTO.ok(operateLogVO); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/annotation/OperateLog.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/annotation/OperateLog.java new file mode 100644 index 0000000..a13be6d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/annotation/OperateLog.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.base.module.support.operatelog.annotation; + +import java.lang.annotation.*; + +/** + * 用户操作日志 注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Documented +public @interface OperateLog { + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/core/OperateLogAspect.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/core/OperateLogAspect.java new file mode 100644 index 0000000..dd723ba --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/core/OperateLogAspect.java @@ -0,0 +1,291 @@ +package net.lab1024.sa.base.module.support.operatelog.core; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartIpUtil; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.module.support.operatelog.OperateLogDao; +import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogEntity; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.boot.context.properties.bind.BindResult; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.ModelAndView; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 操作日志记录处理,对所有OperateLog注解的Controller进行操作日志监控 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Aspect +public abstract class OperateLogAspect { + + private static final String POINT_CUT = "@within(net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog) || @annotation(net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog)"; + + @Resource + private ApplicationContext applicationContext; + /** + * 线程池 + */ + private ThreadPoolTaskExecutor taskExecutor; + + public abstract OperateLogConfig getOperateLogConfig(); + + public OperateLogAspect() { + this.initThread(); + } + + @Pointcut(POINT_CUT) + public void logPointCut() { + } + + @AfterReturning(pointcut = "logPointCut()", returning = "responseDTO") + public void doAfterReturning(JoinPoint joinPoint, Object responseDTO) { + handleLog(joinPoint, null, responseDTO); + } + + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) { + handleLog(joinPoint, e, null); + } + + /** + * 初始化线程池 + */ + private void initThread() { + OperateLogConfig config = getOperateLogConfig(); + int corePoolSize = Runtime.getRuntime().availableProcessors(); + if (null != config.getCorePoolSize()) { + corePoolSize = config.getCorePoolSize(); + } + taskExecutor = new ThreadPoolTaskExecutor(); + //线程初始化 + taskExecutor.initialize(); + // 设置核心线程数 + taskExecutor.setCorePoolSize(corePoolSize); + // 设置最大线程数 + taskExecutor.setMaxPoolSize(corePoolSize * 2); + // 设置队列容量 + taskExecutor.setQueueCapacity(1000); + // 设置线程活跃时间(秒) + taskExecutor.setKeepAliveSeconds(60); + // 设置默认线程名称 + taskExecutor.setThreadNamePrefix("smart-operate-log"); + // 设置拒绝策略 + taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + // 等待所有任务结束后再关闭线程池 + taskExecutor.setWaitForTasksToCompleteOnShutdown(true); + } + + protected void handleLog(final JoinPoint joinPoint, final Exception e, Object responseDTO) { + try { + OperateLog operateLog = this.getAnnotationLog(joinPoint); + if (operateLog == null) { + return; + } + this.submitLog(joinPoint, e, responseDTO); + } catch (Exception exp) { + log.error("保存操作日志异常:{}", exp.getMessage()); + } + } + + private OperateLog getAnnotationLog(JoinPoint joinPoint) throws Exception { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + OperateLog classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), OperateLog.class); + if (classAnnotation != null) { + return classAnnotation; + } + OperateLog methodAnnotation = AnnotationUtils.findAnnotation(method, OperateLog.class); + return methodAnnotation; + } + + /** + * swagger tag + * + * @param joinPoint + * @return + * @throws Exception + */ + private Tag getApi(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + Tag classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Tag.class); + if (method != null) { + return classAnnotation; + } + return null; + } + + /** + * swagger ApiOperation + * + * @param joinPoint + * @return + * @throws Exception + */ + private Operation getApiOperation(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + if (method != null) { + return method.getAnnotation(Operation.class); + } + return null; + } + + /** + * 提交存储操作日志 + * + */ + private void submitLog(final JoinPoint joinPoint, final Throwable e, Object responseDTO) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + //设置用户信息 + RequestUser user = SmartRequestUtil.getRequestUser(); + if (user == null) { + return; + } + + Object[] args = joinPoint.getArgs(); + String params = buildParamString(args); + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + String operateMethod = className + "." + methodName; + String failReason = null; + boolean successFlag = true; + if (e != null) { + successFlag = false; + failReason = getExceptionString(e); + } + + OperateLogEntity operateLogEntity = + OperateLogEntity.builder() + .operateUserId(user.getUserId()) + .operateUserType(user.getUserType().getValue()) + .operateUserName(user.getUserName()) + .url(request.getRequestURI()) + .method(operateMethod) + .param(params) + .ip(user.getIp()) + .ipRegion(SmartIpUtil.getRegion(user.getIp())) + .userAgent(user.getUserAgent()) + .failReason(failReason) + .successFlag(successFlag).build(); + + Operation apiOperation = this.getApiOperation(joinPoint); + if (apiOperation != null) { + operateLogEntity.setContent(apiOperation.summary()); + } + + Tag api = this.getApi(joinPoint); + if (api != null) { + String name = api.name(); + operateLogEntity.setModule(StrUtil.join(",", name)); + } + + // 处理返回值 ResponseDTO + if(responseDTO instanceof ResponseDTO) { + ResponseDTO response = (ResponseDTO) responseDTO; + ResponseDTO logResponseDTO = new ResponseDTO( + response.getCode(), + response.getLevel(), + response.getOk(), + response.getMsg(), + null + ); + logResponseDTO.setDataType(response.getDataType()); + operateLogEntity.setResponse(JSON.toJSONString(logResponseDTO)); + } + + taskExecutor.execute(() -> { + this.saveLog(operateLogEntity); + }); + } + + private String buildParamString(Object[] args) { + if (args == null || args.length == 0) { + return StringConst.EMPTY; + } + + List filterArgs = new ArrayList<>(); + for (Object arg : args) { + if (arg == null) { + continue; + } + if (arg instanceof HttpServletRequest + || arg instanceof HttpServletResponse + || arg instanceof ModelAndView + || arg instanceof MultipartFile + || arg instanceof BindResult) { + continue; + } + filterArgs.add(arg); + } + return JSON.toJSONString(filterArgs); + } + + + private String getExceptionString(Throwable e) { + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw);) { + e.printStackTrace(pw); + } + return sw.toString(); + } + + /** + * 保存操作日志 + * + * @param operateLogEntity + * @return + */ + private Boolean saveLog(OperateLogEntity operateLogEntity) { + OperateLogConfig operateLogConfig = getOperateLogConfig(); + if (operateLogConfig.getSaveFunction() == null) { + BaseMapper mapper = applicationContext.getBean(OperateLogDao.class); + if (mapper == null) { + return false; + } + mapper.insert(operateLogEntity); + return true; + } + return operateLogConfig.getSaveFunction().apply(operateLogEntity); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig.java new file mode 100644 index 0000000..0e8727c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.base.module.support.operatelog.core; + +import lombok.Builder; +import lombok.Data; +import net.lab1024.sa.base.module.support.operatelog.domain.OperateLogEntity; + +import java.util.function.Function; + +/** + * 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@Builder +public class OperateLogConfig { + + /** + * 操作日志存储方法 + */ + private Function saveFunction; + + /** + * 核心线程数 + */ + private Integer corePoolSize; + + /** + * 队列大小 + */ + private Integer queueCapacity; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity.java new file mode 100644 index 0000000..013d24d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity.java @@ -0,0 +1,116 @@ +package net.lab1024.sa.base.module.support.operatelog.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 操作记录 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_operate_log") +public class OperateLogEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long operateLogId; + + /** + * 操作人id + */ + private Long operateUserId; + + /** + * 用户类型 + */ + private Integer operateUserType; + + /** + * 操作人名称 + */ + private String operateUserName; + /** + * 操作模块 + */ + private String module; + + /** + * 操作内容 + */ + private String content; + + /** + * 请求路径 + */ + private String url; + + /** + * 请求方法 + */ + private String method; + + /** + * 请求参数 + */ + private String param; + + /** + * 返回值 + */ + private String response; + + /** + * 客户ip + */ + private String ip; + + /** + * 客户ip地区 + */ + private String ipRegion; + + /** + * user-agent + */ + private String userAgent; + + /** + * 请求结果 0失败 1成功 + */ + private Boolean successFlag; + + /** + * 失败原因 + */ + private String failReason; + + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogQueryForm.java new file mode 100644 index 0000000..5e9bc70 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogQueryForm.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.base.module.support.operatelog.domain; + +import net.lab1024.sa.base.common.domain.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 操作日志查询 表单 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class OperateLogQueryForm extends PageParam { + + @Schema(description = "用户ID") + private Long operateUserId; + + @Schema(description = "用户类型") + private Integer operateUserType; + + @Schema(description = "关键字:模块、操作内容") + private String keywords; + + @Schema(description = "请求关键字:请求地址、请求方法、请求参数") + private String requestKeywords; + + @Schema(description = "开始日期") + private String startDate; + + @Schema(description = "结束日期") + private String endDate; + + + @Schema(description = "用户名称") + private String userName; + + @Schema(description = "请求结果 false失败 true成功") + private Boolean successFlag; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogVO.java new file mode 100644 index 0000000..a657098 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogVO.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.base.module.support.operatelog.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.swagger.SchemaEnum; + +import java.time.LocalDateTime; + +/** + * 操作日志信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class OperateLogVO { + + @Schema(description = "主键") + private Long operateLogId; + + @Schema(description = "用户id") + private Long operateUserId; + + @SchemaEnum(value = UserTypeEnum.class, desc = "用户类型") + private Integer operateUserType; + + @Schema(description = "用户名称") + private String operateUserName; + + @Schema(description = "操作模块") + private String module; + + @Schema(description = "操作内容") + private String content; + + @Schema(description = "请求路径") + private String url; + + @Schema(description = "请求方法") + private String method; + + @Schema(description = "请求参数") + private String param; + + @Schema(description = "返回值") + private String response; + + @Schema(description = "客户ip") + private String ip; + + @Schema(description = "客户ip地区") + private String ipRegion; + + @Schema(description = "user-agent") + private String userAgent; + + @Schema(description = "请求结果 0失败 1成功") + private Boolean successFlag; + + @Schema(description = "失败原因") + private String failReason; + + @Schema(description = "更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime updateTime; + + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime createTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/CustomRedisCacheManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/CustomRedisCacheManager.java new file mode 100644 index 0000000..4ff66aa --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/CustomRedisCacheManager.java @@ -0,0 +1,145 @@ +package net.lab1024.sa.base.module.support.redis; + +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.convert.DurationStyle; +import org.springframework.data.redis.cache.*; + +import java.time.Duration; + +import static net.lab1024.sa.base.common.constant.StringConst.COLON; + +/** + * 自定义 RedisCacheManager,支持在 cacheName 中通过 '#' 指定 TTL(过期时间)。 + * + * @Author CoderKK + * @Date 2025-08-15 13:01:01 + *

+ * 支持格式:{@code cacheName#ttl},其中 ttl 支持 Spring 的 Duration 格式。 + * 特殊值:{@code -1} 表示永久缓存(永不过期)。 + *

+ * + *

使用示例:

+ *
+ * // 10 秒后过期
+ * @Cacheable(value = "user#10s", key = "#id")
+ * // 2 小时后过期
+ * @Cacheable(value = "report#2h", key = "#date")
+ * // 30 分钟后过期
+ * @Cacheable(value = "session#30m", key = "#token")
+ * // 永不过期(永久缓存),适用于极少变化的配置数据
+ * @Cacheable(value = "appConfig#-1", key = "'globalSettings'")
+ * // 无 TTL,使用全局默认过期时间(如 7 天)
+ * @Cacheable(value = "product", key = "#productId")
+ * 
+ * + *

生成的 Redis Key 格式:

+ *
+ * cache:cacheName:key
+ * 例如:cache:user:123
+ *      cache:appConfig:globalSettings
+ * 
+ * + *

支持的 TTL 单位:

+ *
    + *
  • {@code ms} / {@code millis} / {@code milliseconds} - 毫秒
  • + *
  • {@code s} / {@code secs} / {@code seconds} - 秒
  • + *
  • {@code m} / {@code mins} / {@code minutes} - 分钟
  • + *
  • {@code h} / {@code hrs} / {@code hours} - 小时
  • + *
  • {@code d} / {@code days} - 天
  • + *
+ * + *

注意事项:

+ *
    + *
  • 不写单位默认为毫秒
  • + *
  • 永久缓存(#-1)不会自动过期,请配合 @CacheEvict 手动清理。
  • + *
  • 避免对频繁更新的数据使用永久缓存,防止数据陈旧。
  • + *
  • cacheName 中的 '#' 只解析第一个,后续字符将作为 TTL 处理。
  • + *
+ */ +@Slf4j +public class CustomRedisCacheManager extends RedisCacheManager { + + /** + * 缓存全局前缀 + */ + private static final String CACHE_PREFIX = "cache"; + + /** + * 自定义 TTL 分隔符,用于在 cacheName 后附加过期时间 + */ + private static final String CUSTOM_TTL_SEPARATOR = "#"; + + /** + * 默认缓存过期时间:7 天 + */ + private static final Duration DEFAULT_TTL = Duration.ofDays(7); + + public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { + super(cacheWriter, defaultCacheConfiguration); + } + + /** + * 创建 RedisCache 实例,支持从 cacheName 解析 TTL + * + * @param name 缓存名称(支持 name#ttl 格式) + * @param cacheConfig 默认缓存配置 + * @return RedisCache + */ + @Override + protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { + Duration ttl = parseTtlFromCacheName(name); + if (ttl == null) { + ttl = DEFAULT_TTL; + } + + CacheKeyPrefix keyPrefix = cacheName -> { + if (StrUtil.isBlank(cacheName)) { + return CACHE_PREFIX + COLON; + } + String[] parts = cacheName.split(CUSTOM_TTL_SEPARATOR, 2); + String cleanName = StrUtil.trim(parts[0]); + return CACHE_PREFIX + COLON + cleanName + COLON; + }; + + // 构建最终缓存配置:设置 key 前缀 + TTL + RedisCacheConfiguration config = cacheConfig.computePrefixWith(keyPrefix).entryTtl(ttl); + + return super.createRedisCache(name, config); + } + + /** + * 从 cacheName 中解析 TTL + * + * @param name 缓存名称,格式如:users#10m, products#2h, config#-1(永久) + * @return 解析出的 Duration若无效则返回 null;若为 -1,则返回 Duration.ofMillis(-1) 表示永久缓存 + */ + private Duration parseTtlFromCacheName(String name) { + if (StrUtil.isBlank(name)) { + return null; + } + + String[] parts = name.split(CUSTOM_TTL_SEPARATOR, 2); + if (parts.length < 2) { + return null; // 无 TTL 部分 + } + + String ttlStr = StrUtil.trim(parts[1]); + if (StrUtil.isBlank(ttlStr)) { + return null; + } + + // 特殊处理:-1 表示永久缓存 + if ("-1".equals(ttlStr)) { + return Duration.ofMillis(-1); // Spring Redis 中负数 Duration 表示永不过期 + } + + try { + Duration ttl = DurationStyle.detectAndParse(ttlStr); + return ttl.getSeconds() > 0 ? ttl : null; + } catch (IllegalArgumentException e) { + log.error("解析缓存 TTL 失败,cacheName='{}', ttl='{}', 错误: {}", name, ttlStr, e); + return null; + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedisService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedisService.java new file mode 100644 index 0000000..d6fb3cf --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedisService.java @@ -0,0 +1,224 @@ +package net.lab1024.sa.base.module.support.redis; + +import com.alibaba.fastjson.JSON; +import net.lab1024.sa.base.common.domain.SystemEnvironment; +import net.lab1024.sa.base.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.constant.RedisKeyConst; +import org.slf4j.Logger; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * redis 一顿操作 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/25 21:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class RedisService { + + private static final Logger log = org.slf4j.LoggerFactory.getLogger(RedisService.class); + + @Resource + private StringRedisTemplate stringRedisTemplate; + + @Resource + private RedisTemplate redisTemplate; + + @Resource + private ValueOperations redisValueOperations; + + @Resource + private HashOperations redisHashOperations; + + @Resource + private ListOperations redisListOperations; + + @Resource + private SetOperations redisSetOperations; + + @Resource + private SystemEnvironment systemEnvironment; + + + /** + * 生成redis key + * @param prefix + * @param key + * @return + */ + public String generateRedisKey(String prefix, String key) { + SystemEnvironmentEnum currentEnvironment = systemEnvironment.getCurrentEnvironment(); + return systemEnvironment.getProjectName() + RedisKeyConst.SEPARATOR + currentEnvironment.getValue() + RedisKeyConst.SEPARATOR + prefix + key; + } + + /** + * redis key 解析成真实的内容 + * @param redisKey + * @return + */ + public static String redisKeyParse(String redisKey) { + if(SmartStringUtil.isBlank(redisKey)){ + return ""; + } + int index = redisKey.lastIndexOf(RedisKeyConst.SEPARATOR); + if(index < 1){ + return redisKey; + } + return redisKey.substring(index); + } + + public boolean getLock(String key, long expire) { + return redisValueOperations.setIfAbsent(key, String.valueOf(System.currentTimeMillis()), expire, TimeUnit.MILLISECONDS); + } + + public void unLock(String key) { + redisValueOperations.getOperations().delete(key); + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + return redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + + /** + * 获取当天剩余的秒数 + * + * @return + */ + public static long currentDaySecond() { + return ChronoUnit.SECONDS.between(LocalDateTime.now(), LocalDateTime.of(LocalDate.now(), LocalTime.MAX)); + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + return redisTemplate.hasKey(key); + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void delete(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete((Collection) CollectionUtils.arrayToList(key)); + } + } + } + + /** + * 删除缓存 + * + * @param keyList + */ + public void delete(List keyList) { + if (CollectionUtils.isEmpty(keyList)) { + return; + } + redisTemplate.delete(keyList); + } + + //============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public String get(String key) { + return key == null ? null : redisValueOperations.get(key); + } + + public T getObject(String key, Class clazz) { + Object json = this.get(key); + if (json == null) { + return null; + } + T obj = JSON.parseObject(json.toString(), clazz); + return obj; + } + + + /** + * 普通缓存放入 + */ + public void set(String key, String value) { + redisValueOperations.set(key, value); + } + public void set(Object key, Object value) { + String jsonString = JSON.toJSONString(value); + redisValueOperations.set(key.toString(), jsonString); + } + + /** + * 普通缓存放入 + */ + public void set(String key, String value, long second) { + redisValueOperations.set(key, value, second, TimeUnit.SECONDS); + } + + /** + * 普通缓存放入并设置时间 + */ + public void set(Object key, Object value, long second) { + String jsonString = JSON.toJSONString(value); + if (second > 0) { + redisValueOperations.set(key.toString(), jsonString, second, TimeUnit.SECONDS); + } else { + set(key.toString(), jsonString); + } + } + + //============================ map ============================= + + + public void mset(String key, String hashKey, Object value) { + redisHashOperations.put(key, hashKey, value); + } + + public Object mget(String key, String hashKey) { + return redisHashOperations.get(key, hashKey); + } + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedissonPasswordConfigurationCustomizer.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedissonPasswordConfigurationCustomizer.java new file mode 100644 index 0000000..3781ca8 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedissonPasswordConfigurationCustomizer.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.base.module.support.redis; + +import net.lab1024.sa.base.common.util.SmartStringUtil; +import org.redisson.config.Config; +import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer; +import org.springframework.stereotype.Component; + +/** + * + * redission对于password 为空处理有问题,重新设置下 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2024/7/16 01:04:18 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ + +@Component +public class RedissonPasswordConfigurationCustomizer implements RedissonAutoConfigurationCustomizer { + @Override + public void customize(Config configuration) { + if (configuration.isSingleConfig() && SmartStringUtil.isEmpty(configuration.useSingleServer().getPassword())) { + configuration.useSingleServer().setPassword(null); + } + + if (configuration.isClusterConfig() && SmartStringUtil.isEmpty(configuration.useClusterServers().getPassword())) { + configuration.useClusterServers().setPassword(null); + } + if (configuration.isSentinelConfig() && SmartStringUtil.isEmpty(configuration.useSentinelServers().getPassword())) { + configuration.useSentinelServers().setPassword(null); + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedissonService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedissonService.java new file mode 100644 index 0000000..aaab74a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/redis/RedissonService.java @@ -0,0 +1,139 @@ +package net.lab1024.sa.base.module.support.redis; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.exception.BusinessException; +import org.redisson.api.RBucket; +import org.redisson.api.RIdGenerator; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +/** + * Redisson 业务 + * + * @author huke + * @date 2024/6/19 20:39 + */ +@Slf4j +@Service +public class RedissonService { + + @Autowired + private final RedissonClient redissonClient; + + public RedissonService(RedissonClient redissonClient) { + this.redissonClient = redissonClient; + } + + public RedissonClient getRedissonClient() { + return redissonClient; + } + + /** + * 获取锁 并 执行程序 + * + * @param lockKey + * @param waitTime 毫秒 + * @param lockTime 毫秒 + * @param supplier + */ + public T executeWithLock(String lockKey, long waitTime, long lockTime, Supplier supplier) { + // 获取锁 + RLock lock = this.tryLock(lockKey, waitTime, lockTime); + try { + return supplier.get(); + } finally { + // 释放锁 + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + } + + /** + * 获取锁 并 执行程序 + * + * @param lockKey + * @param waitTime 毫秒 + * @param lockTime 毫秒 + * @param runnable + */ + public void executeWithLock(String lockKey, long waitTime, long lockTime, Runnable runnable) { + // 获取锁 + RLock lock = this.tryLock(lockKey, waitTime, lockTime); + try { + runnable.run(); + } finally { + // 释放锁 + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + } + + /** + * 尝试获取锁 + * 最多等待 waitTime 毫秒 + * 获取锁成功后占用 lockTime 毫秒 + * ps:需要手动解锁 lock.unlock() + * + * @param lockKey + * @param waitTime 毫秒 + * @param lockTime 毫秒 + * @return + */ + public RLock tryLock(String lockKey, long waitTime, long lockTime) { + RLock lock = redissonClient.getLock(lockKey); + try { + boolean getLock = lock.tryLock(waitTime, lockTime, TimeUnit.MILLISECONDS); + if (getLock) { + return lock; + } + } catch (InterruptedException e) { + log.error("Redisson tryLock", e); + } + throw new BusinessException("业务繁忙,请稍后重试~"); + } + + /** + * 获取 id 生成器 + * nextId 可生成连续不重复的id + * + * @param key + * @return + */ + public RIdGenerator idGenerator(String key) { + return redissonClient.getIdGenerator(key); + } + + /** + * 存放任意数据类型 + * + * @param key + * @param v + * @param duration + * @param + */ + public void putObj(String key, T v, Duration duration) { + redissonClient.getBucket(key).set(v, duration); + } + + /** + * 获取任意数据类型 + * + * @param key + * @param clazz + * @param + * @return 如果没有找到则返回null + */ + public T getObj(String key, Class clazz) { + RBucket bucket = redissonClient.getBucket(key); + return bucket.get(); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/ReloadCommand.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/ReloadCommand.java new file mode 100644 index 0000000..7b73fed --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/ReloadCommand.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.base.module.support.reload; + +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.module.support.reload.core.AbstractSmartReloadCommand; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadItem; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadResult; +import net.lab1024.sa.base.module.support.reload.dao.ReloadItemDao; +import net.lab1024.sa.base.module.support.reload.dao.ReloadResultDao; +import net.lab1024.sa.base.module.support.reload.domain.ReloadItemEntity; +import net.lab1024.sa.base.module.support.reload.domain.ReloadResultEntity; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * reload 操作 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Component +public class ReloadCommand extends AbstractSmartReloadCommand { + + @Resource + private ReloadItemDao reloadItemDao; + + @Resource + private ReloadResultDao reloadResultDao; + + /** + * 读取数据库中SmartReload项 + * + * @return List + */ + @Override + public List readReloadItem() { + List reloadItemEntityList = reloadItemDao.selectList(null); + return SmartBeanUtil.copyList(reloadItemEntityList, SmartReloadItem.class); + } + + + /** + * 保存reload结果 + * + * @param smartReloadResult + */ + @Override + public void handleReloadResult(SmartReloadResult smartReloadResult) { + ReloadResultEntity reloadResultEntity = SmartBeanUtil.copy(smartReloadResult, ReloadResultEntity.class); + reloadResultDao.insert(reloadResultEntity); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/ReloadService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/ReloadService.java new file mode 100644 index 0000000..eb919e1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/ReloadService.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.base.module.support.reload; + +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.reload.dao.ReloadItemDao; +import net.lab1024.sa.base.module.support.reload.dao.ReloadResultDao; +import net.lab1024.sa.base.module.support.reload.domain.ReloadForm; +import net.lab1024.sa.base.module.support.reload.domain.ReloadItemEntity; +import net.lab1024.sa.base.module.support.reload.domain.ReloadItemVO; +import net.lab1024.sa.base.module.support.reload.domain.ReloadResultVO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class ReloadService { + + @Resource + private ReloadItemDao reloadItemDao; + + @Resource + private ReloadResultDao reloadResultDao; + + /** + * 查询 + * + * @return + */ + public ResponseDTO> query() { + List list = reloadItemDao.query(); + return ResponseDTO.ok(list); + } + + public ResponseDTO> queryReloadItemResult(String tag) { + List reloadResultList = reloadResultDao.query(tag); + return ResponseDTO.ok(reloadResultList); + } + + + /** + * 通过标签更新标识符 + * + * @param reloadForm + * @return + */ + public ResponseDTO updateByTag(ReloadForm reloadForm) { + ReloadItemEntity reloadItemEntity = reloadItemDao.selectById(reloadForm.getTag()); + if (null == reloadItemEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + reloadItemEntity.setIdentification(reloadForm.getIdentification()); + reloadItemEntity.setUpdateTime(LocalDateTime.now()); + reloadItemEntity.setArgs(reloadForm.getArgs()); + reloadItemDao.updateById(reloadItemEntity); + return ResponseDTO.ok(); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/AbstractSmartReloadCommand.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/AbstractSmartReloadCommand.java new file mode 100644 index 0000000..a19aa06 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/AbstractSmartReloadCommand.java @@ -0,0 +1,96 @@ +package net.lab1024.sa.base.module.support.reload.core; + + +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadItem; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadObject; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadResult; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 检测是否 Reload 的类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public abstract class AbstractSmartReloadCommand { + + /** + * 当前ReloadItem的存储器 + */ + private ConcurrentHashMap tagIdentifierMap = new ConcurrentHashMap<>(); + + private SmartReloadManager smartReloadManager; + + /** + * @return + */ + public void setReloadManager(SmartReloadManager smartReloadManager) { + this.smartReloadManager = smartReloadManager; + } + + public void init() { + List smartReloadItems = this.readReloadItem(); + if (smartReloadItems != null) { + for (SmartReloadItem smartReloadItem : smartReloadItems) { + tagIdentifierMap.put(smartReloadItem.getTag(), smartReloadItem.getIdentification()); + } + } + } + + + /** + * 该方法返回一个List:
+ * ReloadItem对象的tagIdentify为:该tag的 状态(状态其实就是个字符串,如果该字符串跟上次有变化则进行reload操作)
+ * ReloadItem对象的args为: reload操作需要的参数

+ * + * @return List + */ + public abstract List readReloadItem(); + + /** + * 处理Reload结果 + * + * @param smartReloadResult + */ + public abstract void handleReloadResult(SmartReloadResult smartReloadResult); + + + /** + * 获取本地缓存tag标识 + * + * @return + */ + public ConcurrentHashMap getTagIdentifierMap() { + return tagIdentifierMap; + } + + /** + * 设置新的缓存标识 + * + * @param tag + * @param identification + */ + public void putIdentifierMap(String tag, String identification) { + tagIdentifierMap.put(tag, identification); + } + + + /** + * 获取重载对象 + * + * @return + */ + public SmartReloadObject reloadObject(String tag) { + if (this.smartReloadManager == null) { + return null; + } + Map reloadObjectMap = smartReloadManager.reloadObjectMap(); + return reloadObjectMap.get(tag); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/SmartReloadManager.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/SmartReloadManager.java new file mode 100644 index 0000000..966715d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/SmartReloadManager.java @@ -0,0 +1,122 @@ +package net.lab1024.sa.base.module.support.reload.core; + + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadObject; +import net.lab1024.sa.base.module.support.reload.core.thread.SmartReloadRunnable; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; +import org.springframework.util.ReflectionUtils; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * SmartReloadManager 管理器 + *

+ * 可以在此类中添加 检测任务 以及注册 处理程序 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +@Service +public class SmartReloadManager implements BeanPostProcessor { + + private static final String THREAD_NAME_PREFIX = "smart-reload"; + private static final int THREAD_COUNT = 1; + + @Value("${reload.interval-seconds}") + private Integer intervalSeconds; + + @Resource + private AbstractSmartReloadCommand reloadCommand; + + private final Map reloadObjectMap = new ConcurrentHashMap<>(); + + private ScheduledThreadPoolExecutor threadPoolExecutor; + + + @PostConstruct + public void init() { + if (threadPoolExecutor != null) { + return; + } + + this.threadPoolExecutor = new ScheduledThreadPoolExecutor(THREAD_COUNT, r -> { + Thread t = new Thread(r, THREAD_NAME_PREFIX); + if (!t.isDaemon()) { + t.setDaemon(true); + } + return t; + }); + this.threadPoolExecutor.scheduleWithFixedDelay(new SmartReloadRunnable(this.reloadCommand), 10, this.intervalSeconds, TimeUnit.SECONDS); + this.reloadCommand.setReloadManager(this); + } + + + @PreDestroy + public void shutdown() { + if (this.threadPoolExecutor != null) { + this.threadPoolExecutor.shutdownNow(); + this.threadPoolExecutor = null; + } + } + + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + Method[] methods = ReflectionUtils.getAllDeclaredMethods(bean.getClass()); + for (Method method : methods) { + SmartReload smartReload = method.getAnnotation(SmartReload.class); + if (smartReload == null) { + continue; + } + int paramCount = method.getParameterCount(); + if (paramCount > 1) { + log.error("<> register tag reload : " + smartReload.value() + " , param count cannot greater than one !"); + continue; + } + String reloadTag = smartReload.value(); + this.register(reloadTag, new SmartReloadObject(bean, method)); + } + return bean; + } + + /** + * 注册reload + * + * @param tag + * @param smartReloadObject + */ + private void register(String tag, SmartReloadObject smartReloadObject) { + if (reloadObjectMap.containsKey(tag)) { + log.error("<> register duplicated tag reload : " + tag + " , and it will be cover!"); + } + reloadObjectMap.put(tag, smartReloadObject); + } + + /** + * 获取重载对象 + * + * @return + */ + public Map reloadObjectMap() { + return this.reloadObjectMap; + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/annoation/SmartReload.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/annoation/SmartReload.java new file mode 100644 index 0000000..0dc3f5b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/annoation/SmartReload.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.base.module.support.reload.core.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 定义 SmartReload 注解 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SmartReload { + + String value(); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadItem.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadItem.java new file mode 100644 index 0000000..19dc6be --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadItem.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.module.support.reload.core.domain; + +import lombok.Data; + +/** + * reload项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class SmartReloadItem { + + /** + * 项名称 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 标识 + */ + private String identification; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadObject.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadObject.java new file mode 100644 index 0000000..c05efd2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadObject.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.module.support.reload.core.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.lang.reflect.Method; + +/** + * Reload 处理程序的实现方法,用于包装以注解 SmartReload 实现的处理类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@AllArgsConstructor +public class SmartReloadObject { + + /** + * 方法对应的实例化对象 + */ + private Object reloadObject; + + /** + * 重新加载执行的方法 + */ + private Method method; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadResult.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadResult.java new file mode 100644 index 0000000..2a38c02 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadResult.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.module.support.reload.core.domain; + +import lombok.Data; + +/** + * t_reload_result 表 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class SmartReloadResult { + + /** + * 项名称 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 标识 + */ + private String identification; + + /** + * 处理结果 + */ + private boolean result; + + /** + * 异常说明 + */ + private String exception; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/thread/SmartReloadRunnable.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/thread/SmartReloadRunnable.java new file mode 100644 index 0000000..0e656c0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/core/thread/SmartReloadRunnable.java @@ -0,0 +1,120 @@ +package net.lab1024.sa.base.module.support.reload.core.thread; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.module.support.reload.core.AbstractSmartReloadCommand; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadItem; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadObject; +import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadResult; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * reload 线程 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class SmartReloadRunnable implements Runnable { + + private AbstractSmartReloadCommand abstractSmartReloadCommand; + + private boolean isInit = false; + + public SmartReloadRunnable(AbstractSmartReloadCommand abstractSmartReloadCommand) { + this.abstractSmartReloadCommand = abstractSmartReloadCommand; + } + + @Override + public void run() { + try { + this.doTask(); + } catch (Throwable e) { + log.error("", e); + } + } + + /** + * 检测Identifier变化,执行reload + */ + private void doTask() { + if (!isInit) { + this.abstractSmartReloadCommand.init(); + isInit = true; + return; + } + + List smartReloadItemList = this.abstractSmartReloadCommand.readReloadItem(); + ConcurrentHashMap tagIdentifierMap = this.abstractSmartReloadCommand.getTagIdentifierMap(); + for (SmartReloadItem smartReloadItem : smartReloadItemList) { + String tag = smartReloadItem.getTag(); + String tagIdentifier = smartReloadItem.getIdentification(); + String preTagChangeIdentifier = tagIdentifierMap.get(tag); + // 数据不一致 + if (preTagChangeIdentifier == null || !preTagChangeIdentifier.equals(tagIdentifier)) { + this.abstractSmartReloadCommand.putIdentifierMap(tag, tagIdentifier); + // 执行重新加载此项的动作 + SmartReloadResult smartReloadResult = this.doReload(smartReloadItem); + this.abstractSmartReloadCommand.handleReloadResult(smartReloadResult); + } + } + } + + /** + * 方法调用 + * + * @param smartReloadItem + * @return + */ + private SmartReloadResult doReload(SmartReloadItem smartReloadItem) { + SmartReloadResult result = new SmartReloadResult(); + SmartReloadObject smartReloadObject = this.abstractSmartReloadCommand.reloadObject(smartReloadItem.getTag()); + try { + if (smartReloadObject == null) { + result.setResult(false); + result.setException("不能从系统中找到对应的tag:" + smartReloadItem.getTag()); + return result; + } + + Method method = smartReloadObject.getMethod(); + if (method == null) { + result.setResult(false); + result.setException("reload方法不存在"); + return result; + } + + result.setTag(smartReloadItem.getTag()); + result.setArgs(smartReloadItem.getArgs()); + result.setIdentification(smartReloadItem.getIdentification()); + result.setResult(true); + int paramCount = method.getParameterCount(); + if (paramCount > 1) { + result.setResult(false); + result.setException("reload方法" + method.getName() + "参数太多"); + return result; + } + + if (paramCount == 0) { + method.invoke(smartReloadObject.getReloadObject()); + } else { + method.invoke(smartReloadObject.getReloadObject(), smartReloadItem.getArgs()); + } + } catch (Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + throwable.printStackTrace(pw); + + result.setResult(false); + result.setException(throwable.toString()); + } + return result; + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/dao/ReloadItemDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/dao/ReloadItemDao.java new file mode 100644 index 0000000..30fe8f8 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/dao/ReloadItemDao.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.base.module.support.reload.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.reload.domain.ReloadItemEntity; +import net.lab1024.sa.base.module.support.reload.domain.ReloadItemVO; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * t_reload_item 数据表dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface ReloadItemDao extends BaseMapper { + + List query(); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/dao/ReloadResultDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/dao/ReloadResultDao.java new file mode 100644 index 0000000..93cb07a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/dao/ReloadResultDao.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.base.module.support.reload.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.reload.domain.ReloadResultEntity; +import net.lab1024.sa.base.module.support.reload.domain.ReloadResultVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * t_reload_result 数据表dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface ReloadResultDao extends BaseMapper { + + List query(@Param("tag") String tag); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadForm.java new file mode 100644 index 0000000..f2b4bbf --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.base.module.support.reload.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ReloadForm { + + @Schema(description = "标签") + @NotBlank(message = "标签不能为空") + private String tag; + + @Schema(description = "状态标识") + @NotBlank(message = "状态标识不能为空") + private String identification; + + @Schema(description = "参数") + private String args; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadItemEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadItemEntity.java new file mode 100644 index 0000000..9c24af9 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadItemEntity.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.base.module.support.reload.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * t_reload_item 数据表 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_reload_item") +public class ReloadItemEntity { + + /** + * 加载项标签 + */ + @TableId(type = IdType.INPUT) + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 运行标识 + */ + private String identification; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadItemVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadItemVO.java new file mode 100644 index 0000000..a9c81e4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadItemVO.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.base.module.support.reload.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class ReloadItemVO { + + @Schema(description = "加载项标签") + private String tag; + + @Schema(description = "参数") + private String args; + + @Schema(description = "运行标识") + private String identification; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadResultEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadResultEntity.java new file mode 100644 index 0000000..7516e6c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadResultEntity.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.base.module.support.reload.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * reload结果
+ * t_reload_result 数据表 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_reload_result") +public class ReloadResultEntity { + + /** + * 加载项标签 + */ + @TableId(type= IdType.NONE) + private String tag; + + /** + * 运行标识 + */ + private String identification; + + /** + * 参数 + */ + private String args; + + /** + * 运行结果 + */ + private Boolean result; + + /** + * 异常 + */ + private String exception; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadResultVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadResultVO.java new file mode 100644 index 0000000..0326904 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/reload/domain/ReloadResultVO.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.reload.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * reload结果 + */ +@Data +public class ReloadResultVO { + + @Schema(description = "加载项标签") + private String tag; + + @Schema(description = "参数") + private String args; + + @Schema(description = "运行结果") + private Boolean result; + + @Schema(description = "异常") + private String exception; + + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/RepeatSubmitAspect.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/RepeatSubmitAspect.java new file mode 100644 index 0000000..2ad0a7b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/RepeatSubmitAspect.java @@ -0,0 +1,98 @@ +package net.lab1024.sa.base.module.support.repeatsubmit; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit; +import net.lab1024.sa.base.module.support.repeatsubmit.ticket.AbstractRepeatSubmitTicket; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * 重复提交 aop切口
+ * -------------------------
+ * 着重说明:
+ * 注解属性 intervalMilliSecond 是指 一段时间内只允许有一次请求;
+ * intervalMilliSecond = 0: 表示只有上个请求执行完以后才可以执行
+ * intervalMilliSecond > 0: 表示指定时间内只才能执行,特别提醒
+ * ------------------------
+ * 特殊说明 intervalMilliSecond > 0
+ * 若假设 方法执行时间为 100ms,若 intervalMilliSecond = 50,则 同一时间内可能会有2个请求同时在执行!
+ * 若假设 方法执行时间为 100ms,若 intervalMilliSecond = 200,则 同一时间内只能有1请求执行,且执行完后100ms,才会执行下一次请求
+ * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2025-07-26 23:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Aspect +@Slf4j +public class RepeatSubmitAspect { + + private final AbstractRepeatSubmitTicket repeatSubmitTicket; + + /** + * 获取凭证信息 + */ + public RepeatSubmitAspect(AbstractRepeatSubmitTicket repeatSubmitTicket) { + this.repeatSubmitTicket = repeatSubmitTicket; + } + + /** + * 定义切入点 + */ + @Around("@annotation(net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit)") + public Object around(ProceedingJoinPoint point) throws Throwable { + + + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + return point.proceed(); + } + + /** + * 第一步:生成防重复提交的 ticket凭证 + * ticket 是根据 Request对象 自定义 生成的,可以加入请求user相关属性作为生成要素 + */ + + HttpServletRequest request = attributes.getRequest(); + String ticket = this.repeatSubmitTicket.generateTicket(request); + if (StringUtils.isEmpty(ticket)) { + return point.proceed(); + } + + Method method = ((MethodSignature) point.getSignature()).getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + Long intervalMilliSecond = (long) annotation.intervalMilliSecond(); + + /** + * 第二步:根据 ticket 凭证进行 加锁 + * 能加锁,则可以执行 + * 若不能加锁,则证明还是时间间隔interval中 + */ + + boolean lockSuccessFlag = this.repeatSubmitTicket.tryLock(ticket, System.currentTimeMillis(), intervalMilliSecond); + if (!lockSuccessFlag) { + return ResponseDTO.error(UserErrorCode.REPEAT_SUBMIT); + } + + try { + return point.proceed(); + } catch (Throwable throwable) { + log.error(throwable.getMessage(), throwable); + throw throwable; + } finally { + this.repeatSubmitTicket.unLock(ticket, intervalMilliSecond); + } + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/annoation/RepeatSubmit.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/annoation/RepeatSubmit.java new file mode 100644 index 0000000..18bec0c --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/annoation/RepeatSubmit.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.base.module.support.repeatsubmit.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 标记 需要防止重复提交 的注解
+ * 单位:毫秒
+ * -------------------------
+ * 着重说明:
+ * 注解属性 intervalMilliSecond 是指 一段时间内只允许有一次请求;
+ * intervalMilliSecond = 0: 表示只有上个请求执行完以后才可以执行
+ * intervalMilliSecond > 0: 表示指定时间内只才能执行,特别提醒
+ * ------------------------
+ * 特殊说明 intervalMilliSecond > 0
+ * 若假设 方法执行时间为 100ms,若 intervalMilliSecond = 50,则 同一时间内可能会有2个请求同时在执行!
+ * 若假设 方法执行时间为 100ms,若 intervalMilliSecond = 200,则 同一时间内只能有1请求执行,且执行完后100ms,才会执行下一次请求
+ * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2025-07-26 20:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface RepeatSubmit { + + /** + * 间隔时间/毫秒 + */ + int intervalMilliSecond() default 0; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java new file mode 100644 index 0000000..845ab0a --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.base.module.support.repeatsubmit.ticket; + +import javax.servlet.http.HttpServletRequest; +import java.util.function.Function; + +/** + * 凭证(用于校验重复提交的东西) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2025-07-26 23:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public abstract class AbstractRepeatSubmitTicket { + + private final Function generateTicketFunction; + + + public AbstractRepeatSubmitTicket(Function generateTicketFunction) { + this.generateTicketFunction = generateTicketFunction; + } + + + /** + * 生成 加锁的 凭证 + */ + public String generateTicket(HttpServletRequest request) { + return this.generateTicketFunction.apply(request); + } + + /** + * 加锁 + */ + public abstract boolean tryLock(String ticket, Long currentTimestamp, Long intervalMilliSecond); + + /** + * 移除锁 + */ + public abstract void unLock(String ticket, Long intervalMilliSecond); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitMemoryTicket.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitMemoryTicket.java new file mode 100644 index 0000000..376ca93 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitMemoryTicket.java @@ -0,0 +1,60 @@ +package net.lab1024.sa.base.module.support.repeatsubmit.ticket; + +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import com.google.common.collect.Maps; + +import javax.servlet.http.HttpServletRequest; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Function; + +/** + * 凭证(内存实现) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2025-07-26 23:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class RepeatSubmitMemoryTicket extends AbstractRepeatSubmitTicket { + + private Interner pool = Interners.newStrongInterner(); + + private ConcurrentMap ticketMap = Maps.newConcurrentMap(); + + public RepeatSubmitMemoryTicket(Function ticketFunction) { + super(ticketFunction); + } + + @Override + public boolean tryLock(String ticket, Long currentTimestamp, Long intervalMilliSecond) { + synchronized (pool.intern(ticket)) { + Long lastTime = ticketMap.putIfAbsent(ticket, currentTimestamp); + if (lastTime == null) { + return true; + } + + if (intervalMilliSecond <= 0) { + return false; + } + + if (currentTimestamp - lastTime < intervalMilliSecond) { + return false; + + } + ticketMap.put(ticket, currentTimestamp); + return true; + } + } + + @Override + public void unLock(String ticket, Long intervalMilliSecond) { + if (intervalMilliSecond > 0) { + return; + } + ticketMap.remove(ticket); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java new file mode 100644 index 0000000..6bb86e4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.base.module.support.repeatsubmit.ticket; + +import org.springframework.data.redis.core.RedisTemplate; + +import javax.servlet.http.HttpServletRequest; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +/** + * 凭证(redis实现) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2025-07-26 23:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public class RepeatSubmitRedisTicket extends AbstractRepeatSubmitTicket { + + private final RedisTemplate redisTemplate; + + public RepeatSubmitRedisTicket(RedisTemplate redisTemplate, + Function ticketFunction) { + super(ticketFunction); + this.redisTemplate = redisTemplate; + } + + @Override + public boolean tryLock(String ticket, Long currentTimestamp, Long intervalMilliSecond) { + if (intervalMilliSecond > 0) { + return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(ticket, String.valueOf(currentTimestamp), intervalMilliSecond, TimeUnit.MILLISECONDS)); + } else { + return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(ticket, String.valueOf(currentTimestamp))); + } + } + + @Override + public void unLock(String ticket, Long intervalMilliSecond) { + if (intervalMilliSecond > 0) { + return; + } + + redisTemplate.delete(ticket); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/dao/LoginFailDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/dao/LoginFailDao.java new file mode 100644 index 0000000..587dd43 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/dao/LoginFailDao.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.securityprotect.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailEntity; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailQueryForm; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 登录失败 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface LoginFailDao extends BaseMapper { + + /** + * 根据用户id和类型查询 + * + * @param userId + * @param userType + * @return + */ + LoginFailEntity selectByUserIdAndUserType(@Param("userId") Long userId, @Param("userType") Integer userType); + + /** + * 根据用户id和类型查询 进行删除 + * + * @param userId + * @param userType + * @return + */ + void deleteByUserIdAndUserType(@Param("userId") Long userId, @Param("userType") Integer userType); + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") LoginFailQueryForm queryForm); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/dao/PasswordLogDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/dao/PasswordLogDao.java new file mode 100644 index 0000000..77dae29 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/dao/PasswordLogDao.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.base.module.support.securityprotect.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.securityprotect.domain.PasswordLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Mapper +public interface PasswordLogDao extends BaseMapper { + + /** + * 查询最后一次修改密码记录 + * + * @param userType + * @param userId + * @return + */ + PasswordLogEntity selectLastByUserTypeAndUserId(@Param("userType") Integer userType, @Param("userId") Long userId); + + + /** + * 查询最近几次修改后的密码 + * + * @param userType + * @param userId + * @return + */ + List selectOldPassword(@Param("userType") Integer userType, @Param("userId") Long userId, @Param("limit") int limit); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/Level3ProtectConfigForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/Level3ProtectConfigForm.java new file mode 100644 index 0000000..3f8fa3b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/Level3ProtectConfigForm.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.base.module.support.securityprotect.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 三级等保相关配置 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/7/30 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ + +@Data +public class Level3ProtectConfigForm { + + @Schema(description = "连续登录失败次数则锁定") + @NotNull(message = "连续登录失败次数则锁定 不能为空") + private Integer loginFailMaxTimes; + + @Schema(description = "连续登录失败锁定时间(单位:分钟)") + @NotNull(message = "连续登录失败锁定时间(单位:分钟) 不能为空") + private Integer loginFailLockMinutes; + + @Schema(description = "最低活跃时间(单位:分钟)") + @NotNull(message = "最低活跃时间(单位:分钟) 不能为空") + private Integer loginActiveTimeoutMinutes; + + @Schema(description = "开启双因子登录") + @NotNull(message = "开启双因子登录 不能为空") + private Boolean twoFactorLoginEnabled; + + @Schema(description = "密码复杂度 是否开启,默认:开启") + @NotNull(message = "密码复杂度 是否开启 不能为空") + private Boolean passwordComplexityEnabled; + + @Schema(description = "定期修改密码时间间隔(默认:月)") + @NotNull(message = "定期修改密码时间间隔(默认:月) 不能为空") + private Integer regularChangePasswordMonths; + + @Schema(description = "定期修改密码不允许重复次数,默认:3次以内密码不能相同(默认:次)") + @NotNull(message = "定期修改密码不允许重复次数 不能为空") + private Integer regularChangePasswordNotAllowRepeatTimes; + + @Schema(description = "文件检测,默认:不开启") + @NotNull(message = "文件检测 是否开启 不能为空") + private Boolean fileDetectFlag; + + @Schema(description = "文件大小限制,单位 mb ,(默认:50 mb)") + @NotNull(message = "文件大小限制 不能为空") + private Long maxUploadFileSizeMb; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity.java new file mode 100644 index 0000000..f1219b4 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity.java @@ -0,0 +1,66 @@ +package net.lab1024.sa.base.module.support.securityprotect.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 登录失败记录 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/11 19:29:18 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Data +@Builder +@TableName("t_login_fail") +public class LoginFailEntity { + + + @TableId(type = IdType.AUTO) + private Long loginFailId; + + /** + * 用户id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 登录名 + */ + private String loginName; + + /** + * 锁定状态 + */ + private Boolean lockFlag; + + /** + * 登录失败次数 + */ + private Integer loginFailCount; + + /** + * 连续登录失败锁定开始时间 + */ + private LocalDateTime loginLockBeginTime; + + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailQueryForm.java new file mode 100644 index 0000000..41c048b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.base.module.support.securityprotect.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 登录失败 分页查询表单 + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2023-10-17 18:02:37 + * @Copyright 1024创新实验室 + */ + +@Data +public class LoginFailQueryForm extends PageParam { + + @Schema(description = "登录名") + private String loginName; + + @Schema(description = "锁定状态") + private Boolean lockFlag; + + @Schema(description = "登录失败锁定时间") + private LocalDate loginLockBeginTimeBegin; + + @Schema(description = "登录失败锁定时间") + private LocalDate loginLockBeginTimeEnd; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailVO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailVO.java new file mode 100644 index 0000000..317ee74 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailVO.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.base.module.support.securityprotect.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 登录失败 列表VO + * + * @Author 1024创新实验室-主任-卓大 + * @Date 2023-10-17 18:02:37 + * @Copyright 1024创新实验室 + */ + +@Data +public class LoginFailVO { + + private Long loginFailId; + + + @Schema(description = "用户id") + private Long userId; + + @Schema(description = "用户类型") + private Integer userType; + + @Schema(description = "登录名") + private String loginName; + + @Schema(description = "连续登录失败次数") + private Integer loginFailCount; + + @Schema(description = "锁定状态:1锁定,0未锁定") + private Integer lockFlag; + + @Schema(description = "连续登录失败锁定开始时间") + private LocalDateTime loginLockBeginTime; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/PasswordLogEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/PasswordLogEntity.java new file mode 100644 index 0000000..93927dc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/domain/PasswordLogEntity.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.base.module.support.securityprotect.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author yandy + * @description: + * @date 2024/7/15 1:39 下午 + */ +@Data +@TableName("t_password_log") +public class PasswordLogEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long id; + + private Integer userType; + + private Long userId; + + private String oldPassword; + + private String newPassword; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/Level3ProtectConfigService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/Level3ProtectConfigService.java new file mode 100644 index 0000000..3282fcf --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/Level3ProtectConfigService.java @@ -0,0 +1,189 @@ +package net.lab1024.sa.base.module.support.securityprotect.service; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.base.module.support.config.ConfigService; +import net.lab1024.sa.base.module.support.securityprotect.domain.Level3ProtectConfigForm; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; + +/** + * 三级等保配置 + * + * @Author 1024创新实验室-创始人兼主任:卓大 + * @Date 2024/7/30 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ,Since 2012 + */ + +@Service +@Slf4j +public class Level3ProtectConfigService { + + /** + * 开启双因子登录,默认:开启 + * -- GETTER -- + * 开启双因子登录,默认:开启 + + */ + @Getter + private boolean twoFactorLoginEnabled = false; + + /** + * 连续登录失败次数则锁定,-1表示不受限制,可以一直尝试登录 + * -- GETTER -- + * 连续登录失败次数则锁定,-1表示不受限制,可以一直尝试登录 + + */ + @Getter + private int loginFailMaxTimes = -1; + + /** + * 连续登录失败锁定时间(单位:秒),-1表示不锁定,建议锁定30分钟 + * -- GETTER -- + * 连续登录失败锁定时间(单位:秒),-1表示不锁定,建议锁定30分钟 + + */ + @Getter + private int loginFailLockSeconds = 1800; + + /** + * 最低活跃时间(单位:秒),超过此时间没有操作系统就会被冻结,默认-1 代表不限制,永不冻结; 默认 30分钟 + */ + private int loginActiveTimeoutSeconds = -1; + + /** + * 密码复杂度 是否开启,默认:开启 + * -- GETTER -- + * 密码复杂度 是否开启,默认:开启 + + */ + @Getter + private boolean passwordComplexityEnabled = true; + + /** + * 定期修改密码时间间隔(默认:天),默认:建议90天更换密码 + * -- GETTER -- + * 定期修改密码时间间隔(默认:天),默认:建议90天更换密码 + + */ + @Getter + private int regularChangePasswordDays = 90; + + /** + * 定期修改密码不允许相同次数,默认:3次以内密码不能相同 + * -- GETTER -- + * 定期修改密码不允许相同次数,默认:3次以内密码不能相同 + + */ + @Getter + private int regularChangePasswordNotAllowRepeatTimes = 3; + + /** + * 文件大小限制,单位 mb ,(默认:50 mb) + * -- GETTER -- + * 文件大小限制,单位 mb ,(默认:50 mb) + + */ + @Getter + private long maxUploadFileSizeMb = 50; + + /** + * 文件检测,默认:不开启 + * -- GETTER -- + * 文件检测,默认:不开启 + + */ + @Getter + private boolean fileDetectFlag = false; + + + @Resource + private ConfigService configService; + + /** + * 最低活跃时间(单位:秒),超过此时间没有操作系统就会被冻结,默认-1 代表不限制,永不冻结; 默认 30分钟 + */ + public int getLoginActiveTimeoutSeconds() { + return loginActiveTimeoutSeconds > 0 ? loginActiveTimeoutSeconds : -1; + } + + @PostConstruct + void init() { + String configValue = configService.getConfigValue(ConfigKeyEnum.LEVEL3_PROTECT_CONFIG); + if (StrUtil.isEmpty(configValue)) { + throw new ExceptionInInitializerError("t_config 表 三级等保配置为空,请进行配置!"); + } + Level3ProtectConfigForm level3ProtectConfigForm = JSON.parseObject(configValue, Level3ProtectConfigForm.class); + setProp(level3ProtectConfigForm); + } + + /** + * 设置属性 + */ + private void setProp(Level3ProtectConfigForm configForm) { + + if (configForm.getFileDetectFlag() != null) { + this.fileDetectFlag = configForm.getFileDetectFlag(); + } + + if (configForm.getMaxUploadFileSizeMb() != null) { + this.maxUploadFileSizeMb = configForm.getMaxUploadFileSizeMb(); + } + + if (configForm.getLoginFailMaxTimes() != null) { + this.loginFailMaxTimes = configForm.getLoginFailMaxTimes(); + } + + if (configForm.getLoginFailLockMinutes() != null) { + this.loginFailLockSeconds = configForm.getLoginFailLockMinutes() * 60; + } + + if (configForm.getLoginActiveTimeoutMinutes() != null) { + this.loginActiveTimeoutSeconds = configForm.getLoginActiveTimeoutMinutes() * 60; + this.loginActiveTimeoutSeconds = loginActiveTimeoutSeconds > 0 ? loginActiveTimeoutSeconds : -1; + } + + if (configForm.getPasswordComplexityEnabled() != null) { + this.passwordComplexityEnabled = configForm.getPasswordComplexityEnabled(); + } + + if (configForm.getRegularChangePasswordMonths() != null) { + this.regularChangePasswordDays = configForm.getRegularChangePasswordMonths() * 30; + } + + if (configForm.getTwoFactorLoginEnabled() != null) { + this.twoFactorLoginEnabled = configForm.getTwoFactorLoginEnabled(); + } + + if (configForm.getRegularChangePasswordNotAllowRepeatTimes() != null) { + this.regularChangePasswordNotAllowRepeatTimes = configForm.getRegularChangePasswordNotAllowRepeatTimes(); + } + + // 设置 最低活跃时间(单位:秒) + if (this.loginActiveTimeoutSeconds > 0) { + StpUtil.getStpLogic().getConfigOrGlobal().setActiveTimeout(getLoginActiveTimeoutSeconds()); + } else { + StpUtil.getStpLogic().getConfigOrGlobal().setActiveTimeout(-1); + } + } + + /** + * 更新三级等保配置 + */ + public ResponseDTO updateLevel3Config(Level3ProtectConfigForm configForm) { + // 设置属性 + setProp(configForm); + // 保存数据库 + String configFormJsonString = JSON.toJSONString(configForm, true); + return configService.updateValueByKey(ConfigKeyEnum.LEVEL3_PROTECT_CONFIG, configFormJsonString); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityFileService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityFileService.java new file mode 100644 index 0000000..3d17fa1 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityFileService.java @@ -0,0 +1,107 @@ +package net.lab1024.sa.base.module.support.securityprotect.service; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.apache.commons.io.IOUtils; +import org.apache.tika.config.TikaConfig; +import org.apache.tika.exception.TikaException; +import org.apache.tika.io.TikaInputStream; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.metadata.TikaCoreProperties; +import org.apache.tika.mime.MediaType; +import org.apache.tika.mime.MimeTypes; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +/** + * 三级等保 文件 相关 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2024/08/22 19:25:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Service +@Slf4j +public class SecurityFileService { + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + // 定义白名单MIME类型 + private static final List ALLOWED_MIME_TYPES = Arrays.asList("application/json", "application/zip", "application/x-7z-compressed", "application/pdf", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-works", "text/csv", "audio/*", "video/*", + // 图片类型 svg有安全隐患,所以不使用"image/*" + "image/jpeg", "image/png", "image/gif", "image/bmp"); + + /** + * 检测文件安全类型 + */ + public ResponseDTO checkFile(MultipartFile file) { + + // 检验文件大小 + if (level3ProtectConfigService.getMaxUploadFileSizeMb() > 0) { + long maxSize = level3ProtectConfigService.getMaxUploadFileSizeMb() * 1024 * 1024; + if (file.getSize() > maxSize) { + return ResponseDTO.userErrorParam("上传文件最大为:" + level3ProtectConfigService.getMaxUploadFileSizeMb() + " mb"); + } + } + + // 文件类型安全检测 + if (level3ProtectConfigService.isFileDetectFlag()) { + String fileType = getFileMimeType(file); + if (ALLOWED_MIME_TYPES.stream().noneMatch(allowedType -> matchesMimeType(fileType, allowedType))) { + return ResponseDTO.userErrorParam("禁止上传此文件类型"); + } + } + + return ResponseDTO.ok(); + } + + /** + * 获取文件的 MIME 类型 + * + * @param file 要检查的文件 + * @return 文件的 MIME 类型 + */ + public static String getFileMimeType(MultipartFile file) { + InputStream inputStream = null; + try { + inputStream = file.getInputStream(); + TikaConfig tika = new TikaConfig(); + Metadata metadata = new Metadata(); + metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, file.getOriginalFilename()); + TikaInputStream stream = TikaInputStream.get(inputStream); + MediaType mimetype = tika.getDetector().detect(stream, metadata); + return mimetype.toString(); + } catch (IOException | TikaException e) { + log.error(e.getMessage(), e); + return MimeTypes.OCTET_STREAM; + } finally { + IOUtils.closeQuietly(inputStream); + } + } + + /** + * 检查文件的 MIME 类型是否与指定的MIME 类型匹配(支持通配符) + * + * @param fileType 文件的 MIME 类型 + * @param mimetype MIME 类型(支持通配符) + * @return 是否匹配 + */ + private static boolean matchesMimeType(String fileType, String mimetype) { + if (mimetype.endsWith("/*")) { + String prefix = mimetype.substring(0, mimetype.length() - 1); + return fileType.startsWith(prefix); + } else { + return fileType.equalsIgnoreCase(mimetype); + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityLoginService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityLoginService.java new file mode 100644 index 0000000..4088ff2 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityLoginService.java @@ -0,0 +1,175 @@ +package net.lab1024.sa.base.module.support.securityprotect.service; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.code.UserErrorCode; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.enumeration.UserTypeEnum; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.securityprotect.dao.LoginFailDao; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailEntity; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailQueryForm; +import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 三级等保 登录 相关 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/11 19:25:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Service +public class SecurityLoginService { + + private static final String LOGIN_LOCK_MSG = "您已连续登录失败%s次,账号锁定%s分钟,解锁时间为:%s,请您耐心等待!"; + + private static final String LOGIN_FAIL_MSG = "登录名或密码错误!连续登录失败%s次,账号将锁定%s分钟!您还可以再尝试%s次!"; + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + @Resource + private LoginFailDao loginFailDao; + + + /** + * 检查是否可以登录 + * + * @param userId + * @param userType + * @return + */ + public ResponseDTO checkLogin(Long userId, UserTypeEnum userType) { + + // 若登录最大失败次数小于1,无需校验 + if (level3ProtectConfigService.getLoginFailMaxTimes() < 1) { + return ResponseDTO.ok(); + } + + + LoginFailEntity loginFailEntity = loginFailDao.selectByUserIdAndUserType(userId, userType.getValue()); + if (loginFailEntity == null) { + return ResponseDTO.ok(); + } + + // 校验登录失败次数 + if (loginFailEntity.getLoginFailCount() < level3ProtectConfigService.getLoginFailMaxTimes()) { + return ResponseDTO.ok(loginFailEntity); + } + + // 校验是否锁定 + if (loginFailEntity.getLoginLockBeginTime() == null) { + return ResponseDTO.ok(loginFailEntity); + } + + // 校验锁定时长 + if (loginFailEntity.getLoginLockBeginTime().plusSeconds(level3ProtectConfigService.getLoginFailLockSeconds()).isBefore(LocalDateTime.now())) { + // 过了锁定时间 + return ResponseDTO.ok(loginFailEntity); + } + + LocalDateTime unlockTime = loginFailEntity.getLoginLockBeginTime().plusSeconds(level3ProtectConfigService.getLoginFailLockSeconds()); + return ResponseDTO.error(UserErrorCode.LOGIN_FAIL_LOCK, String.format(LOGIN_LOCK_MSG, loginFailEntity.getLoginFailCount(), level3ProtectConfigService.getLoginFailLockSeconds() / 60, LocalDateTimeUtil.formatNormal(unlockTime))); + } + + /** + * 登录失败后记录 + * + * @param userId + * @param userType + * @param loginFailEntity + */ + public String recordLoginFail(Long userId, UserTypeEnum userType, String loginName, LoginFailEntity loginFailEntity) { + + // 若登录最大失败次数小于1,无需记录 + if (level3ProtectConfigService.getLoginFailMaxTimes() < 1) { + return null; + } + + // 登录失败 + int loginFailCount = loginFailEntity == null ? 1 : loginFailEntity.getLoginFailCount() + 1; + boolean lockFlag = loginFailCount >= level3ProtectConfigService.getLoginFailMaxTimes(); + LocalDateTime lockBeginTime = lockFlag ? LocalDateTime.now() : null; + + if (loginFailEntity == null) { + loginFailEntity = LoginFailEntity.builder() + .userId(userId) + .userType(userType.getValue()) + .loginName(loginName) + .loginFailCount(loginFailCount) + .lockFlag(lockFlag) + .loginLockBeginTime(lockBeginTime) + .build(); + loginFailDao.insert(loginFailEntity); + } else { + loginFailEntity.setLoginLockBeginTime(lockBeginTime); + loginFailEntity.setLoginFailCount(loginFailCount); + loginFailEntity.setLockFlag(lockFlag); + loginFailEntity.setLoginName(loginName); + loginFailDao.updateById(loginFailEntity); + } + + // 提示信息 + if (lockFlag) { + LocalDateTime unlockTime = loginFailEntity.getLoginLockBeginTime().plusSeconds(level3ProtectConfigService.getLoginFailLockSeconds()); + return String.format(LOGIN_LOCK_MSG, loginFailEntity.getLoginFailCount(), level3ProtectConfigService.getLoginFailLockSeconds() / 60, LocalDateTimeUtil.formatNormal(unlockTime)); + } else { + return String.format(LOGIN_FAIL_MSG, level3ProtectConfigService.getLoginFailMaxTimes(), level3ProtectConfigService.getLoginFailLockSeconds() / 60, level3ProtectConfigService.getLoginFailMaxTimes() - loginFailEntity.getLoginFailCount()); + } + } + + /** + * 清除登录失败 + * + * @param userId + * @param userType + */ + public void removeLoginFail(Long userId, UserTypeEnum userType) { + + // 若登录最大失败次数小于1,无需校验 + if (level3ProtectConfigService.getLoginFailMaxTimes() < 1) { + return; + } + + loginFailDao.deleteByUserIdAndUserType(userId, userType.getValue()); + } + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(LoginFailQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = loginFailDao.queryPage(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 批量删除 + * + * @param idList + * @return + */ + public ResponseDTO batchDelete(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return ResponseDTO.ok(); + } + + loginFailDao.deleteBatchIds(idList); + return ResponseDTO.ok(); + } + +} +; \ No newline at end of file diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityPasswordService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityPasswordService.java new file mode 100644 index 0000000..b4fc871 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/securityprotect/service/SecurityPasswordService.java @@ -0,0 +1,156 @@ +package net.lab1024.sa.base.module.support.securityprotect.service; + +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.module.support.securityprotect.dao.PasswordLogDao; +import net.lab1024.sa.base.module.support.securityprotect.domain.PasswordLogEntity; +import org.apache.commons.lang3.RandomStringUtils; +import org.springframework.security.crypto.argon2.Argon2PasswordEncoder; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 三级等保 密码 相关 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2023/10/11 19:25:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室,Since 2012 + */ + +@Service +public class SecurityPasswordService { + + /** + * 密码长度8-20位且包含大小写字母、数字、特殊符号三种及以上组合 + */ + public static final String PASSWORD_PATTERN = "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\\W_!@#$%^&*`~()-+=]+$)(?![0-9\\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\\W_!@#$%^&*`~()-+=]*$"; + + public static final String PASSWORD_FORMAT_MSG = "密码必须为长度8-20位且必须包含大小写字母、数字、特殊符号(如:@#$%^&*()_+-=)等三种字符"; + + private static final int PASSWORD_LENGTH = 8; + + + @Resource + private PasswordLogDao passwordLogDao; + + @Resource + private Level3ProtectConfigService level3ProtectConfigService; + + static Argon2PasswordEncoder ARGON2_PASSWORD_ENCODER = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8(); + + /** + * 校验密码复杂度 + */ + public ResponseDTO validatePasswordComplexity(String password) { + + if (SmartStringUtil.isEmpty(password)) { + return ResponseDTO.userErrorParam(PASSWORD_FORMAT_MSG); + } + + // 密码长度必须大于等于8位 + if (password.length() < PASSWORD_LENGTH) { + return ResponseDTO.userErrorParam(PASSWORD_FORMAT_MSG); + } + + // 无需校验 密码复杂度 + if (!level3ProtectConfigService.isPasswordComplexityEnabled()) { + return ResponseDTO.ok(); + } + + if (!password.matches(PASSWORD_PATTERN)) { + return ResponseDTO.userErrorParam(PASSWORD_FORMAT_MSG); + } + + return ResponseDTO.ok(); + } + + /** + * 校验密码重复次数 + */ + public ResponseDTO validatePasswordRepeatTimes(RequestUser requestUser, String newPassword) { + + // 密码重复次数小于1 无需校验 + if (level3ProtectConfigService.getRegularChangePasswordNotAllowRepeatTimes() < 1) { + return ResponseDTO.ok(); + } + + // 检查最近几次是否有重复密码 + List oldPasswords = passwordLogDao.selectOldPassword(requestUser.getUserType().getValue(), requestUser.getUserId(), level3ProtectConfigService.getRegularChangePasswordNotAllowRepeatTimes()); + boolean isDuplicate = oldPasswords.stream().anyMatch(oldPassword -> ARGON2_PASSWORD_ENCODER.matches(newPassword, oldPassword)); + if (isDuplicate) { + return ResponseDTO.userErrorParam(String.format("与前%d个历史密码重复,请换个密码!", level3ProtectConfigService.getRegularChangePasswordNotAllowRepeatTimes())); + } + + return ResponseDTO.ok(); + } + + /** + * 随机生成密码 + */ + public String randomPassword() { + // 未开启密码复杂度,则由8为数字构成 + if (!level3ProtectConfigService.isPasswordComplexityEnabled()) { + return RandomStringUtils.randomNumeric(PASSWORD_LENGTH); + } + + // 3位大写字母,2位数字,2位小写字母 + 1位特殊符号 + return RandomStringUtils.randomAlphabetic(3).toUpperCase() + + RandomStringUtils.randomNumeric(2) + + RandomStringUtils.randomAlphabetic(2).toLowerCase() + + (ThreadLocalRandom.current().nextBoolean() ? "#" : "@"); + } + + + /** + * 保存修改密码 + */ + public void saveUserChangePasswordLog(RequestUser requestUser, String newPassword, String oldPassword) { + + PasswordLogEntity passwordLogEntity = new PasswordLogEntity(); + passwordLogEntity.setNewPassword(newPassword); + passwordLogEntity.setOldPassword(oldPassword); + passwordLogEntity.setUserId(requestUser.getUserId()); + passwordLogEntity.setUserType(requestUser.getUserType().getValue()); + passwordLogDao.insert(passwordLogEntity); + } + + /** + * 检查是否需要修改密码 + */ + public boolean checkNeedChangePassword(Integer userType, Long userId) { + + if (level3ProtectConfigService.getRegularChangePasswordDays() < 1) { + return false; + } + + PasswordLogEntity passwordLogEntity = passwordLogDao.selectLastByUserTypeAndUserId(userType, userId); + if (passwordLogEntity == null) { + return false; + } + + LocalDateTime nextUpdateTime = passwordLogEntity.getCreateTime().plusDays(level3ProtectConfigService.getRegularChangePasswordDays()); + return nextUpdateTime.isBefore(LocalDateTime.now()); + } + + /** + * 获取 加密后 的密码 + */ + public static String getEncryptPwd(String password) { + return ARGON2_PASSWORD_ENCODER.encode(password); + } + + /** + * 校验密码是否匹配 + */ + public static Boolean matchesPwd(String password, String encodedPassword) { + return ARGON2_PASSWORD_ENCODER.matches(password, encodedPassword); + } + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberIdEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberIdEnum.java new file mode 100644 index 0000000..6a12d41 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberIdEnum.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.base.module.support.serialnumber.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 单据序列号 枚举 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum SerialNumberIdEnum implements BaseEnum { + + ORDER(1, "订单id"), + + CONTRACT(2, "合同id"), + + ; + + private final Integer serialNumberId; + + private final String desc; + + @Override + public Integer getValue() { + return serialNumberId; + } + + @Override + public String toString() { + return "SerialNumberIdEnum{" + + "serialNumberId=" + serialNumberId + + ", desc='" + desc + '\'' + + '}'; + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java new file mode 100644 index 0000000..01f4f42 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.base.module.support.serialnumber.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.constant.StringConst; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * 单据序列号 周期 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@AllArgsConstructor +@Getter +public enum SerialNumberRuleTypeEnum implements BaseEnum { + /** + * 没有周期 + */ + NONE(StringConst.EMPTY, "", "没有周期"), + /** + * 年周期 + */ + YEAR("[yyyy]", "\\[yyyy\\]", "年"), + /** + * 月周期 + */ + MONTH("[mm]", "\\[mm\\]", "年月"), + /** + * 日周期 + */ + DAY("[dd]", "\\[dd\\]", "年月日"); + + private final String value; + + private final String regex; + + private final String desc; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberDao.java new file mode 100644 index 0000000..6e3303b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberDao.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.base.module.support.serialnumber.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * 单据序列号 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface SerialNumberDao extends BaseMapper { + + /** + * 排他锁查询 + * + * @param serialNumberId + * @return + */ + SerialNumberEntity selectForUpdate(@Param("serialNumberId") Integer serialNumberId); + + /** + * 更新上一次的 数值和时间 + * + * @param serialNumberId + * @param lastNumber + * @param lastTime + */ + void updateLastNumberAndTime(@Param("serialNumberId") Integer serialNumberId, @Param("lastNumber") Long lastNumber, @Param("lastTime") LocalDateTime lastTime); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberRecordDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberRecordDao.java new file mode 100644 index 0000000..f363cd6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberRecordDao.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.base.module.support.serialnumber.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberRecordEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberRecordQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.util.List; + +/** + * 单据序列号 生成的记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface SerialNumberRecordDao extends BaseMapper { + + /** + * 根据 id和日期 查询 记录id + * + * @param serialNumberId + * @param recordDate + * @return + */ + Long selectRecordIdBySerialNumberIdAndDate(@Param("serialNumberId") Integer serialNumberId, @Param("recordDate") String recordDate); + + /** + * 更新记录 + * + * @param serialNumberId + * @param recordDate + * @param lastNumber + * @param count + * @return + */ + Long updateRecord(@Param("serialNumberId") Integer serialNumberId, @Param("recordDate") LocalDate recordDate, @Param("lastNumber") Long lastNumber, @Param("count") int count); + + /** + * 分页查询记录 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("queryForm") SerialNumberRecordQueryForm queryForm); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberEntity.java new file mode 100644 index 0000000..46ae303 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberEntity.java @@ -0,0 +1,79 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; + +import java.time.LocalDateTime; + +/** + * 单据序列号 定义表 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_serial_number") +public class SerialNumberEntity { + + /** + * 主键id + * + * @see SerialNumberIdEnum + */ + @TableId(type = IdType.INPUT) + private Integer serialNumberId; + + /** + * 业务 + */ + private String businessName; + + /** + * 格式 + */ + private String format; + + /** + * 生成规则 + * + * @see SerialNumberRuleTypeEnum + */ + private String ruleType; + + + /** + * 初始值 + */ + private Long initNumber; + + /** + * 步长随机数范围 + */ + private Integer stepRandomRange; + + /** + * 备注 + */ + private String remark; + + /** + * 上次产生的单号, 默认为空 + */ + private Long lastNumber; + + /** + * 上次产生的单号时间 + */ + private LocalDateTime lastTime; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateForm.java new file mode 100644 index 0000000..a3f2f02 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 单据序列号 生成表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class SerialNumberGenerateForm { + + @Schema(description = "单号id") + @NotNull(message = "单号id不能为空") + private Integer serialNumberId; + + @Schema(description = "生成的数量") + @NotNull(message = "生成的数量") + private Integer count; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java new file mode 100644 index 0000000..6250b61 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 单据序列号 生成结果 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SerialNumberGenerateResultBO { + + /** + * 序号id + */ + private Integer serialNumberId; + + /** + * 是否重置的初始值 + */ + private Boolean isReset; + + /** + * 上次生成的数字 + */ + private Long lastNumber; + + /** + * 上次生成的时间 + */ + private LocalDateTime lastTime; + + /** + * 生成的 number 集合 + */ + private List numberList; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO.java new file mode 100644 index 0000000..4bb3071 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO.java @@ -0,0 +1,97 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; + +/** + * 单据序列号 信息 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SerialNumberInfoBO { + + /** + * 主键id + * + * @see SerialNumberIdEnum + */ + private Integer serialNumberId; + + /** + * 业务 + */ + private String businessName; + + /** + * 格式 + */ + private String format; + + /** + * 生成规则 + * + * @see SerialNumberRuleTypeEnum + */ + private String ruleType; + + + /** + * 初始值 + */ + private Long initNumber; + + /** + * 步长随机数范围 + */ + private Integer stepRandomRange; + + /** + * 备注 + */ + private String remark; + + /** + * 规则枚举 + */ + private SerialNumberRuleTypeEnum serialNumberRuleTypeEnum; + + + /** + * 存在[nnnnnn]中 n 的数量 + */ + private Integer numberCount; + + /** + * [nnnnnn] 的格式(主要用于替换) + */ + private String numberFormat; + + /** + * 是否存在年份 + */ + private Boolean haveYearFlag; + + /** + * 是否存在月份 + */ + private Boolean haveMonthFlag; + + /** + * 是否存在 月 + */ + private Boolean haveDayFlag; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java new file mode 100644 index 0000000..f695df0 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 上次生成信息 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SerialNumberLastGenerateBO { + + /** + * 序号id + */ + private Integer serialNumberId; + + /** + * 上次生成的数字 + */ + private Long lastNumber; + + /** + * 上次生成的时间 + */ + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime lastTime; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity.java new file mode 100644 index 0000000..f7c3a7d --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity.java @@ -0,0 +1,60 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 单据序列号 表结构 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName("t_serial_number_record") +public class SerialNumberRecordEntity { + + /** + * 单号id + */ + @TableId(type= IdType.NONE) + private Integer serialNumberId; + + /** + * 记录日期 + */ + private LocalDate recordDate; + + /** + * 最后更新值 + */ + private Long lastNumber; + + /** + * 上次生成时间 + */ + private LocalDateTime lastTime; + + /** + * 数量 + */ + private Long count; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java new file mode 100644 index 0000000..ef177f3 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.base.module.support.serialnumber.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 单据序列号 生成记录 查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class SerialNumberRecordQueryForm extends PageParam { + + @Schema(description = "单号id") + @NotNull(message = "单号id不能为空") + private Integer serialNumberId; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberBaseService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberBaseService.java new file mode 100644 index 0000000..acbfba6 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberBaseService.java @@ -0,0 +1,256 @@ +package net.lab1024.sa.base.module.support.serialnumber.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.base.common.exception.BusinessException; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; +import net.lab1024.sa.base.module.support.serialnumber.dao.SerialNumberDao; +import net.lab1024.sa.base.module.support.serialnumber.dao.SerialNumberRecordDao; +import net.lab1024.sa.base.module.support.serialnumber.domain.*; +import org.apache.commons.lang3.RandomUtils; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 单据序列号 基类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public abstract class SerialNumberBaseService implements SerialNumberService { + + @Resource + protected SerialNumberRecordDao serialNumberRecordDao; + + @Resource + protected SerialNumberDao serialNumberDao; + + protected ConcurrentHashMap serialNumberMap = new ConcurrentHashMap<>(); + + public abstract List generateSerialNumberList(SerialNumberInfoBO serialNumber, int count); + + @PostConstruct + void init() { + List serialNumberEntityList = serialNumberDao.selectList(null); + if (serialNumberEntityList == null) { + return; + } + for (SerialNumberEntity serialNumberEntity : serialNumberEntityList) { + SerialNumberRuleTypeEnum ruleTypeEnum = SmartEnumUtil.getEnumByName(serialNumberEntity.getRuleType().toUpperCase(), SerialNumberRuleTypeEnum.class); + if (ruleTypeEnum == null) { + throw new ExceptionInInitializerError("cannot find rule type , id : " + serialNumberEntity.getSerialNumberId()); + } + + String format = serialNumberEntity.getFormat(); + int startIndex = format.indexOf("[n"); + int endIndex = format.indexOf("n]"); + if (startIndex == -1 || endIndex == -1 || endIndex <= startIndex) { + throw new ExceptionInInitializerError("[nnn] 配置错误,请仔细查看 id : " + serialNumberEntity.getSerialNumberId()); + } + + String numberFormat = format.substring(startIndex + 1, endIndex + 1); + + if (serialNumberEntity.getStepRandomRange() < 1) { + throw new ExceptionInInitializerError("random step range must greater than 1 " + serialNumberEntity.getSerialNumberId()); + } + + SerialNumberInfoBO serialNumberInfoBO = SerialNumberInfoBO.builder() + .serialNumberId(serialNumberEntity.getSerialNumberId()) + .serialNumberRuleTypeEnum(ruleTypeEnum) + .initNumber(serialNumberEntity.getInitNumber()) + .format(serialNumberEntity.getFormat()) + .stepRandomRange(serialNumberEntity.getStepRandomRange()) + .haveDayFlag(format.contains(SerialNumberRuleTypeEnum.DAY.getValue())) + .haveMonthFlag(format.contains(SerialNumberRuleTypeEnum.MONTH.getValue())) + .haveYearFlag(format.contains(SerialNumberRuleTypeEnum.YEAR.getValue())) + .numberCount(endIndex - startIndex) + .numberFormat("\\[" + numberFormat + "\\]") + .build(); + + this.serialNumberMap.put(serialNumberEntity.getSerialNumberId(), serialNumberInfoBO); + } + + //初始化数据 + initLastGenerateData(serialNumberEntityList); + } + + /** + * 初始化上次生成的数据 + * + * @param serialNumberEntityList + */ + public abstract void initLastGenerateData(List serialNumberEntityList); + + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) + public String generate(SerialNumberIdEnum serialNumberIdEnum) { + List generateList = this.generate(serialNumberIdEnum, 1); + if (generateList == null || generateList.isEmpty()) { + throw new BusinessException("cannot generate : " + serialNumberIdEnum.toString()); + } + return generateList.get(0); + } + + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) + public List generate(SerialNumberIdEnum serialNumberIdEnum, int count) { + SerialNumberInfoBO serialNumberInfoBO = serialNumberMap.get(serialNumberIdEnum.getSerialNumberId()); + if (serialNumberInfoBO == null) { + throw new BusinessException("cannot found SerialNumberId : " + serialNumberIdEnum.toString()); + } + return this.generateSerialNumberList(serialNumberInfoBO, count); + } + + /** + * 循环生成 number 集合 + * + * @param lastGenerate + * @param serialNumberInfo + * @param count + * @return + */ + protected SerialNumberGenerateResultBO loopNumberList(SerialNumberLastGenerateBO lastGenerate, SerialNumberInfoBO serialNumberInfo, int count) { + Long lastNumber = lastGenerate.getLastNumber(); + boolean isReset = false; + if (isResetInitNumber(lastGenerate, serialNumberInfo)) { + lastNumber = serialNumberInfo.getInitNumber(); + isReset = true; + } + + ArrayList numberList = Lists.newArrayListWithCapacity(count); + for (int i = 0; i < count; i++) { + Integer stepRandomRange = serialNumberInfo.getStepRandomRange(); + if (stepRandomRange > 1) { + lastNumber = lastNumber + RandomUtils.nextInt(1, stepRandomRange + 1); + } else { + lastNumber = lastNumber + 1; + } + + numberList.add(lastNumber); + } + + return SerialNumberGenerateResultBO + .builder() + .serialNumberId(serialNumberInfo.getSerialNumberId()) + .lastNumber(lastNumber) + .lastTime(LocalDateTime.now()) + .numberList(numberList) + .isReset(isReset) + .build(); + } + + protected void saveRecord(SerialNumberGenerateResultBO resultBO) { + Long effectRows = serialNumberRecordDao.updateRecord(resultBO.getSerialNumberId(), + resultBO.getLastTime().toLocalDate(), + resultBO.getLastNumber(), + resultBO.getNumberList().size() + ); + + // 需要插入 + if (effectRows == null || effectRows == 0) { + SerialNumberRecordEntity recordEntity = SerialNumberRecordEntity.builder() + .serialNumberId(resultBO.getSerialNumberId()) + .recordDate(LocalDate.now()) + .lastTime(resultBO.getLastTime()) + .lastNumber(resultBO.getLastNumber()) + .count((long) resultBO.getNumberList().size()) + .build(); + serialNumberRecordDao.insert(recordEntity); + } + + } + + /** + * 若不在规则周期内,重制初始值 + * + * @return + */ + private boolean isResetInitNumber(SerialNumberLastGenerateBO lastGenerate, SerialNumberInfoBO serialNumberInfo) { + LocalDateTime lastTime = lastGenerate.getLastTime(); + if (lastTime == null) { + return true; + } + + SerialNumberRuleTypeEnum serialNumberRuleTypeEnum = serialNumberInfo.getSerialNumberRuleTypeEnum(); + int lastTimeYear = lastTime.getYear(); + int lastTimeMonth = lastTime.getMonthValue(); + int lastTimeDay = lastTime.getDayOfYear(); + + LocalDateTime now = LocalDateTime.now(); + + switch (serialNumberRuleTypeEnum) { + case YEAR: + return lastTimeYear != now.getYear(); + case MONTH: + return lastTimeYear != now.getYear() || lastTimeMonth != now.getMonthValue(); + case DAY: + return lastTimeYear != now.getYear() || lastTimeDay != now.getDayOfYear(); + default: + return false; + } + } + + /** + * 替换特殊rule,即替换[yyyy][mm][dd][nnn]等规则 + */ + protected List formatNumberList(SerialNumberGenerateResultBO generateResult, SerialNumberInfoBO serialNumberInfo) { + + /** + * 第一步:替换年、月、日 + */ + LocalDate lastTime = generateResult.getLastTime().toLocalDate(); + String year = String.valueOf(lastTime.getYear()); + String month = lastTime.getMonthValue() > 9 ? String.valueOf(lastTime.getMonthValue()) : "0" + lastTime.getMonthValue(); + String day = lastTime.getDayOfMonth() > 9 ? String.valueOf(lastTime.getDayOfMonth()) : "0" + lastTime.getDayOfMonth(); + + // 把年月日替换 + String format = serialNumberInfo.getFormat(); + + if (serialNumberInfo.getHaveYearFlag()) { + format = format.replaceAll(SerialNumberRuleTypeEnum.YEAR.getRegex(), year); + } + if (serialNumberInfo.getHaveMonthFlag()) { + format = format.replaceAll(SerialNumberRuleTypeEnum.MONTH.getRegex(), month); + } + if (serialNumberInfo.getHaveDayFlag()) { + format = format.replaceAll(SerialNumberRuleTypeEnum.DAY.getRegex(), day); + } + + + /** + * 第二步:替换数字 + */ + + List numberList = Lists.newArrayListWithCapacity(generateResult.getNumberList().size()); + for (Long number : generateResult.getNumberList()) { + StringBuilder numberStringBuilder = new StringBuilder(); + int currentNumberCount = String.valueOf(number).length(); + //数量不够,前面补0 + if (serialNumberInfo.getNumberCount() > currentNumberCount) { + int remain = serialNumberInfo.getNumberCount() - currentNumberCount; + for (int i = 0; i < remain; i++) { + numberStringBuilder.append(0); + } + } + numberStringBuilder.append(number); + //最终替换 + String finalNumber = format.replaceAll(serialNumberInfo.getNumberFormat(), numberStringBuilder.toString()); + numberList.add(finalNumber); + } + return numberList; + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberRecordService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberRecordService.java new file mode 100644 index 0000000..39daa0f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberRecordService.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.base.module.support.serialnumber.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.module.support.serialnumber.dao.SerialNumberRecordDao; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberRecordEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberRecordQueryForm; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 单据序列号 记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class SerialNumberRecordService { + + @Resource + private SerialNumberRecordDao serialNumberRecordDao; + + public PageResult query(SerialNumberRecordQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List recordList = serialNumberRecordDao.query(page, queryForm); + return SmartPageUtil.convert2PageResult(page, recordList); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberService.java new file mode 100644 index 0000000..50d1dbe --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberService.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.base.module.support.serialnumber.service; + +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum; + +import java.util.List; + +/** + * 单据序列号 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +public interface SerialNumberService { + + /** + * 生成 + * + * @param serialNumberIdEnum + * @return + */ + String generate(SerialNumberIdEnum serialNumberIdEnum); + + + /** + * 生成n个 + * + * @param serialNumberIdEnum + * @param count + * @return + */ + List generate(SerialNumberIdEnum serialNumberIdEnum, int count); + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberInternService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberInternService.java new file mode 100644 index 0000000..8a21ebc --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberInternService.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.base.module.support.serialnumber.service.impl; + +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberGenerateResultBO; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberInfoBO; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberLastGenerateBO; +import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberBaseService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 单据序列号 基于内存锁实现 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class SerialNumberInternService extends SerialNumberBaseService { + + /** + * 按照 serialNumberId 进行锁 + */ + private static final Interner POOL = Interners.newStrongInterner(); + + + private ConcurrentHashMap serialNumberLastGenerateMap = new ConcurrentHashMap<>(); + + @Override + public void initLastGenerateData(List serialNumberEntityList) { + if (serialNumberEntityList == null) { + return; + } + + for (SerialNumberEntity serialNumberEntity : serialNumberEntityList) { + SerialNumberLastGenerateBO lastGenerateBO = SerialNumberLastGenerateBO + .builder() + .serialNumberId(serialNumberEntity.getSerialNumberId()) + .lastNumber(serialNumberEntity.getLastNumber()) + .lastTime(serialNumberEntity.getLastTime()) + .build(); + serialNumberLastGenerateMap.put(serialNumberEntity.getSerialNumberId(), lastGenerateBO); + } + } + + @Override + public List generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) { + SerialNumberGenerateResultBO serialNumberGenerateResult = null; + synchronized (POOL.intern(serialNumberInfo.getSerialNumberId())) { + + // 获取上次的生成结果 + SerialNumberLastGenerateBO lastGenerateBO = serialNumberLastGenerateMap.get(serialNumberInfo.getSerialNumberId()); + + // 生成 + serialNumberGenerateResult = super.loopNumberList(lastGenerateBO, serialNumberInfo, count); + + // 将生成信息保存的内存和数据库 + lastGenerateBO.setLastNumber(serialNumberGenerateResult.getLastNumber()); + lastGenerateBO.setLastTime(serialNumberGenerateResult.getLastTime()); + serialNumberDao.updateLastNumberAndTime(serialNumberInfo.getSerialNumberId(), + serialNumberGenerateResult.getLastNumber(), + serialNumberGenerateResult.getLastTime()); + + // 把生成过程保存到数据库里 + super.saveRecord(serialNumberGenerateResult); + } + + return formatNumberList(serialNumberGenerateResult, serialNumberInfo); + } + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberMysqlService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberMysqlService.java new file mode 100644 index 0000000..0d13dc7 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberMysqlService.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.base.module.support.serialnumber.service.impl; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.exception.BusinessException; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberGenerateResultBO; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberInfoBO; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberLastGenerateBO; +import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberBaseService; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 单据序列号 基于mysql锁实现 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class SerialNumberMysqlService extends SerialNumberBaseService { + + @Override + @Transactional(rollbackFor = Throwable.class) + public List generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) { + // // 获取上次的生成结果 + SerialNumberEntity serialNumberEntity = serialNumberDao.selectForUpdate(serialNumberInfo.getSerialNumberId()); + if (serialNumberEntity == null) { + throw new BusinessException("cannot found SerialNumberId 数据库不存在:" + serialNumberInfo.getSerialNumberId()); + } + SerialNumberLastGenerateBO lastGenerateBO = SerialNumberLastGenerateBO + .builder() + .lastNumber(serialNumberEntity.getLastNumber()) + .lastTime(serialNumberEntity.getLastTime()) + .serialNumberId(serialNumberEntity.getSerialNumberId()) + .build(); + + // 生成 + SerialNumberGenerateResultBO serialNumberGenerateResult = super.loopNumberList(lastGenerateBO, serialNumberInfo, count); + + // 将生成信息保存的内存和数据库 + lastGenerateBO.setLastNumber(serialNumberGenerateResult.getLastNumber()); + lastGenerateBO.setLastTime(serialNumberGenerateResult.getLastTime()); + serialNumberDao.updateLastNumberAndTime(serialNumberInfo.getSerialNumberId(), + serialNumberGenerateResult.getLastNumber(), + serialNumberGenerateResult.getLastTime()); + + // 把生成过程保存到数据库里 + super.saveRecord(serialNumberGenerateResult); + + return formatNumberList(serialNumberGenerateResult, serialNumberInfo); + } + + @Override + public void initLastGenerateData(List serialNumberEntityList) { + + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberRedisService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberRedisService.java new file mode 100644 index 0000000..3f78895 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberRedisService.java @@ -0,0 +1,160 @@ +package net.lab1024.sa.base.module.support.serialnumber.service.impl; + +import cn.hutool.core.util.RandomUtil; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.base.common.exception.BusinessException; +import net.lab1024.sa.base.common.util.SmartDateFormatterEnum; +import net.lab1024.sa.base.common.util.SmartEnumUtil; +import net.lab1024.sa.base.common.util.SmartLocalDateUtil; +import net.lab1024.sa.base.common.util.SmartStringUtil; +import net.lab1024.sa.base.constant.RedisKeyConst; +import net.lab1024.sa.base.module.support.redis.RedisService; +import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberGenerateResultBO; +import net.lab1024.sa.base.module.support.serialnumber.domain.SerialNumberInfoBO; +import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberBaseService; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Scheduled; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * 单据序列号 基于redis key-value increase 实现 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2025-08-03 22:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Slf4j +public class SerialNumberRedisService extends SerialNumberBaseService { + + @Resource + private RedisService redisService; + + @Resource + private RedisTemplate redisTemplate; + + @Override + public void initLastGenerateData(List serialNumberEntityList) { + if (serialNumberEntityList == null) { + return; + } + + // 设置redis的上次值 + for (SerialNumberEntity serialNumberEntity : serialNumberEntityList) { + if (serialNumberEntity.getLastTime() == null) { + continue; + } + + String redisKey = generateRedisKeyByDate(serialNumberEntity.getSerialNumberId(), + SmartEnumUtil.getEnumByName(serialNumberEntity.getRuleType().toUpperCase(), SerialNumberRuleTypeEnum.class), + serialNumberEntity.getLastTime().toLocalDate()); + + Object o = redisTemplate.opsForValue().get(redisKey); + if (o == null) { + redisTemplate.opsForValue().set(redisKey, serialNumberEntity.getLastNumber()); + } + } + } + + /** + * 每天凌晨一点进行检测; + * 检测单位数量为3; 3天前、3月前、3年前 + */ + @Scheduled(cron = "0 0 1 * * ?") + public void tryDeleteUnusedRedisKey() { + for (SerialNumberInfoBO serialNumberInfoBO : serialNumberMap.values()) { + SerialNumberRuleTypeEnum typeEnum = serialNumberInfoBO.getSerialNumberRuleTypeEnum(); + String dateStr = ""; + switch (typeEnum) { + case DAY: + dateStr = SmartLocalDateUtil.format(LocalDate.now().minusDays(3), SmartDateFormatterEnum.YMD); + case MONTH: + dateStr = SmartLocalDateUtil.format(LocalDate.now().minusMonths(3), SmartDateFormatterEnum.YM); + case YEAR: + dateStr = String.valueOf(LocalDate.now().minusYears(3)); + } + if (SmartStringUtil.isNotEmpty(dateStr)) { + String redisKey = RedisKeyConst.Support.SERIAL_NUMBER + serialNumberInfoBO.getSerialNumberId() + ":" + dateStr; + redisService.delete(redisKey); + } + } + } + + @Override + public List generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) { + // 根据步长,计算 redis 增加值 + ArrayList list = new ArrayList<>(count); + int redisIncrease = 0; + for (int i = 0; i < count; i++) { + int stepIncrease = 1; + Integer stepRandomRange = serialNumberInfo.getStepRandomRange(); + if (stepRandomRange > 1) { + stepIncrease = RandomUtil.getSecureRandom().nextInt(serialNumberInfo.getStepRandomRange()) + 1; + } + redisIncrease += stepIncrease; + list.add(stepIncrease); + } + try { + String redisKey = generateRedisKeyByDate(serialNumberInfo.getSerialNumberId(), serialNumberInfo.getSerialNumberRuleTypeEnum(), LocalDate.now()); + Long increaseResult = redisTemplate.opsForValue().increment(redisKey, redisIncrease); + + ArrayList numberList = new ArrayList<>(count); + Long number = increaseResult; + for (Integer i : list) { + number = number - i; + numberList.add((number + 1)); + } + + Collections.reverse(numberList); + + SerialNumberGenerateResultBO serialNumberGenerateResult = SerialNumberGenerateResultBO + .builder() + .serialNumberId(serialNumberInfo.getSerialNumberId()) + .lastNumber(increaseResult) + .lastTime(LocalDateTime.now()) + .numberList(numberList) + .isReset(false) + .build(); + + + // 将生成信息保存的内存和数据库 + serialNumberDao.updateLastNumberAndTime(serialNumberInfo.getSerialNumberId(), + serialNumberGenerateResult.getLastNumber(), + serialNumberGenerateResult.getLastTime()); + + // 把生成过程保存到数据库里 + super.saveRecord(serialNumberGenerateResult); + return formatNumberList(serialNumberGenerateResult, serialNumberInfo); + } catch (Throwable e) { + log.error(e.getMessage(), e); + throw e; + } + } + + private String generateRedisKeyByDate(Integer serialNumberId, SerialNumberRuleTypeEnum serialNumberRuleTypeEnum, LocalDate localDate) { + switch (serialNumberRuleTypeEnum) { + case DAY: + String dayStr = SmartLocalDateUtil.format(localDate, SmartDateFormatterEnum.YMD); + return RedisKeyConst.Support.SERIAL_NUMBER + serialNumberId + ":" + dayStr; + case MONTH: + String monthStr = SmartLocalDateUtil.format(localDate, SmartDateFormatterEnum.YM); + return RedisKeyConst.Support.SERIAL_NUMBER + serialNumberId + ":" + monthStr; + case YEAR: + String yearStr = String.valueOf(localDate.getYear()); + return RedisKeyConst.Support.SERIAL_NUMBER + serialNumberId + ":" + yearStr; + case NONE: + return RedisKeyConst.Support.SERIAL_NUMBER + serialNumberId; + default: + throw new BusinessException("serialNumberRuleTypeEnum not exist error"); + } + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnController.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnController.java new file mode 100644 index 0000000..58ee17b --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnController.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.base.module.support.table; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import net.lab1024.sa.base.common.controller.SupportBaseController; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartRequestUtil; +import net.lab1024.sa.base.constant.SwaggerTagConst; +import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit; +import net.lab1024.sa.base.module.support.table.domain.TableColumnUpdateForm; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 表格自定义列(前端用户自定义表格列,并保存到数据库里) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@RestController +@Tag(name = SwaggerTagConst.Support.TABLE_COLUMN) +public class TableColumnController extends SupportBaseController { + + @Resource + private TableColumnService tableColumnService; + + @Operation(summary = "修改表格列 @author 卓大") + @PostMapping("/tableColumn/update") + @RepeatSubmit + public ResponseDTO updateTableColumn(@RequestBody @Valid TableColumnUpdateForm updateForm) { + return tableColumnService.updateTableColumns(SmartRequestUtil.getRequestUser(), updateForm); + } + + @Operation(summary = "恢复默认(删除) @author 卓大") + @GetMapping("/tableColumn/delete/{tableId}") + @RepeatSubmit + public ResponseDTO deleteTableColumn(@PathVariable Integer tableId) { + return tableColumnService.deleteTableColumn(SmartRequestUtil.getRequestUser(), tableId); + } + + @Operation(summary = "查询表格列 @author 卓大") + @GetMapping("/tableColumn/getColumns/{tableId}") + public ResponseDTO getColumns(@PathVariable Integer tableId) { + return ResponseDTO.ok(tableColumnService.getTableColumns(SmartRequestUtil.getRequestUser(), tableId)); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnDao.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnDao.java new file mode 100644 index 0000000..6dbe22f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnDao.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.base.module.support.table; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.base.module.support.table.domain.TableColumnEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 表格自定义列(前端用户自定义表格列,并保存到数据库里) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Mapper +public interface TableColumnDao extends BaseMapper { + + TableColumnEntity selectByUserIdAndTableId(@Param("userId") Long userId, @Param("userType") Integer userType, @Param("tableId") Integer tableId); + + void deleteTableColumn(@Param("userId") Long userId, @Param("userType") Integer userType, @Param("tableId") Integer tableId); +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnService.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnService.java new file mode 100644 index 0000000..6f76fd5 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/TableColumnService.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.base.module.support.table; + +import com.alibaba.fastjson.JSONArray; +import net.lab1024.sa.base.common.domain.RequestUser; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.module.support.table.domain.TableColumnEntity; +import net.lab1024.sa.base.module.support.table.domain.TableColumnUpdateForm; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 表格自定义列(前端用户自定义表格列,并保存到数据库里) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Service +public class TableColumnService { + + @Resource + private TableColumnDao tableColumnDao; + + /** + * 获取 - 表格列 + * + * @return + */ + public String getTableColumns(RequestUser requestUser, Integer tableId) { + TableColumnEntity tableColumnEntity = tableColumnDao.selectByUserIdAndTableId(requestUser.getUserId(), requestUser.getUserType().getValue(), tableId); + return tableColumnEntity == null ? null : tableColumnEntity.getColumns(); + } + + /** + * 更新表格列 + * + * @return + */ + public ResponseDTO updateTableColumns(RequestUser requestUser, TableColumnUpdateForm updateForm) { + if (CollectionUtils.isEmpty(updateForm.getColumnList())) { + return ResponseDTO.ok(); + } + Integer tableId = updateForm.getTableId(); + TableColumnEntity tableColumnEntity = tableColumnDao.selectByUserIdAndTableId(requestUser.getUserId(), requestUser.getUserType().getValue(), tableId); + if (tableColumnEntity == null) { + tableColumnEntity = new TableColumnEntity(); + tableColumnEntity.setTableId(tableId); + tableColumnEntity.setUserId(requestUser.getUserId()); + tableColumnEntity.setUserType(requestUser.getUserType().getValue()); + + tableColumnEntity.setColumns(JSONArray.toJSONString(updateForm.getColumnList())); + tableColumnDao.insert(tableColumnEntity); + } else { + tableColumnEntity.setColumns(JSONArray.toJSONString(updateForm.getColumnList())); + tableColumnDao.updateById(tableColumnEntity); + } + return ResponseDTO.ok(); + } + + /** + * 删除表格列 + * + * @return + */ + public ResponseDTO deleteTableColumn(RequestUser requestUser, Integer tableId) { + tableColumnDao.deleteTableColumn(requestUser.getUserId(), requestUser.getUserType().getValue(), tableId); + return ResponseDTO.ok(); + } +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnEntity.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnEntity.java new file mode 100644 index 0000000..b8b89cb --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnEntity.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.base.module.support.table.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 自定义表格列 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +@TableName("t_table_column") +public class TableColumnEntity { + + @TableId(type = IdType.AUTO) + private Long tableColumnId; + + /** + * 用户id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 表id + */ + private Integer tableId; + + /** + * 表列 + */ + private String columns; + + private LocalDateTime createTime; + + private LocalDateTime updateTime; +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnItemForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnItemForm.java new file mode 100644 index 0000000..1fc1183 --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnItemForm.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.base.module.support.table.domain; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 自定义表格列 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class TableColumnItemForm { + + @NotEmpty(message = "列不能为空") + @Schema(description = "字段") + private String columnKey; + + @Schema(description = "宽度") + private Integer width; + + @NotNull(message = "显示不能为空") + @Schema(description = "是否显示") + private Boolean showFlag; + + @NotNull(message = "排序不能为空") + @Schema(description = "排序") + private Integer sort; + + +} diff --git a/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnUpdateForm.java b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnUpdateForm.java new file mode 100644 index 0000000..5a6139f --- /dev/null +++ b/yun-base/src/main/java/net/lab1024/sa/base/module/support/table/domain/TableColumnUpdateForm.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.base.module.support.table.domain; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 自定义表格列 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 + */ +@Data +public class TableColumnUpdateForm { + + @NotNull(message = "表id不能为空") + private Integer tableId; + + @NotEmpty(message = "请上传列") + private List columnList; + +} diff --git a/yun-base/src/main/resources/META-INF/spring.factories b/yun-base/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..7dc64b8 --- /dev/null +++ b/yun-base/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.env.EnvironmentPostProcessor=\ + net.lab1024.sa.base.config.YamlProcessor \ No newline at end of file diff --git a/yun-base/src/main/resources/banner.txt b/yun-base/src/main/resources/banner.txt new file mode 100644 index 0000000..5e14f0d --- /dev/null +++ b/yun-base/src/main/resources/banner.txt @@ -0,0 +1,13 @@ + ${AnsiColor.BRIGHT_GREEN} + + / ____| | | /\ | | (_) +| (___ _ __ ___ __ _ _ __| |_ / \ __| |_ __ ___ _ _ __ + \___ \| '_ ` _ \ / _` | '__| __| / /\ \ / _` | '_ ` _ \| | '_ \ + ____) | | | | | | (_| | | | |_ / ____ \ (_| | | | | | | | | | | +|_____/|_| |_| |_|\__,_|_| \__/_/ \_\__,_|_| |_| |_|_|_| |_| + +保持谦逊 保持学习 ! +热爱代码 热爱生活 ! +永远年轻 永远前行 ! + +${AnsiColor.DEFAULT} \ No newline at end of file diff --git a/yun-base/src/main/resources/code-generator-template/java/constant/enum.java.vm b/yun-base/src/main/resources/code-generator-template/java/constant/enum.java.vm new file mode 100644 index 0000000..87c2c64 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/constant/enum.java.vm @@ -0,0 +1,24 @@ +package ${packageName}; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * ${enumDesc} + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@AllArgsConstructor +@Getter +public enum ${enumName} implements BaseEnum { + + ; + + private final ${enumJavaType} value; + + private final String desc; +} diff --git a/yun-base/src/main/resources/code-generator-template/java/controller/Controller.java.vm b/yun-base/src/main/resources/code-generator-template/java/controller/Controller.java.vm new file mode 100644 index 0000000..13ccc5b --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/controller/Controller.java.vm @@ -0,0 +1,75 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import cn.dev33.satoken.annotation.SaCheckPermission; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * ${basic.description} Controller + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@RestController +@Tag(name = "${basic.description}") +public class ${name.upperCamel}Controller { + + @Resource + private ${name.upperCamel}Service ${name.lowerCamel}Service; + + @Operation(summary = "分页查询 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/queryPage") + @SaCheckPermission("${name.lowerCamel}:query") + public ResponseDTO> queryPage(@RequestBody @Valid ${name.upperCamel}QueryForm queryForm) { + return ResponseDTO.ok(${name.lowerCamel}Service.queryPage(queryForm)); + } + +#if($insertAndUpdate.isSupportInsertAndUpdate) + @Operation(summary = "添加 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/add") + @SaCheckPermission("${name.lowerCamel}:add") + public ResponseDTO add(@RequestBody @Valid ${name.upperCamel}AddForm addForm) { + return ${name.lowerCamel}Service.add(addForm); + } + + @Operation(summary = "更新 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/update") + @SaCheckPermission("${name.lowerCamel}:update") + public ResponseDTO update(@RequestBody @Valid ${name.upperCamel}UpdateForm updateForm) { + return ${name.lowerCamel}Service.update(updateForm); + } +#end + +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + @Operation(summary = "批量删除 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/batchDelete") + @SaCheckPermission("${name.lowerCamel}:delete") + public ResponseDTO batchDelete(@RequestBody ValidateList<${primaryKeyJavaType}> idList) { + return ${name.lowerCamel}Service.batchDelete(idList); + } + #end + + #if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + @Operation(summary = "单个删除 @author ${basic.backendAuthor}") + @GetMapping("/${name.lowerCamel}/delete/{${primaryKeyFieldName}}") + @SaCheckPermission("${name.lowerCamel}:delete") + public ResponseDTO batchDelete(@PathVariable ${primaryKeyJavaType} ${primaryKeyFieldName}) { + return ${name.lowerCamel}Service.delete(${primaryKeyFieldName}); + } + #end +#end +} diff --git a/yun-base/src/main/resources/code-generator-template/java/dao/Dao.java.vm b/yun-base/src/main/resources/code-generator-template/java/dao/Dao.java.vm new file mode 100644 index 0000000..374c374 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/dao/Dao.java.vm @@ -0,0 +1,51 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * ${basic.description} Dao + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Mapper +public interface ${name.upperCamel}Dao extends BaseMapper<${name.upperCamel}Entity> { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List<${name.upperCamel}VO> queryPage(Page page, @Param("queryForm") ${name.upperCamel}QueryForm queryForm); + +#if($deleteInfo.isSupportDelete) +### 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) +#if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 更新删除状态 + */ + long updateDeleted(@Param("${primaryKeyFieldName}")${primaryKeyJavaType} ${primaryKeyFieldName},@Param("deletedFlag")boolean deletedFlag); + +#end +#if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 批量更新删除状态 + */ + void batchUpdateDeleted(@Param("idList")List<${primaryKeyJavaType}> idList,@Param("deletedFlag")boolean deletedFlag); + +#end +#end +#end +} diff --git a/yun-base/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm b/yun-base/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm new file mode 100644 index 0000000..146f9be --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm @@ -0,0 +1,38 @@ +package ${basic.javaPackageName}.domain.entity; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 实体类 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +@TableName("${tableName}") +public class ${name.upperCamel}Entity { +#foreach ($field in $fields) + + /** + * $field.columnComment + */ + #if($field.primaryKeyFlag && $field.autoIncreaseFlag) + @TableId(type = IdType.AUTO) + #end + #if($field.primaryKeyFlag && !$field.autoIncreaseFlag) + @TableId + #end + #if($field.columnName == "create_time") + @TableField(fill = FieldFill.INSERT) + #end + #if($field.columnName == "update_time") + @TableField(fill = FieldFill.INSERT_UPDATE) + #end + private $field.javaType $field.fieldName; +#end + +} diff --git a/yun-base/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm b/yun-base/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm new file mode 100644 index 0000000..d1e8581 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm @@ -0,0 +1,30 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 新建表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}AddForm { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.notEmpty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/yun-base/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm b/yun-base/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm new file mode 100644 index 0000000..69a247e --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm @@ -0,0 +1,39 @@ +package ${packageName}; + +import net.lab1024.sa.base.common.domain.PageParam; +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 分页查询表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +@EqualsAndHashCode(callSuper = false) +public class ${name.upperCamel}QueryForm extends PageParam { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum && $field.queryTypeEnum != "DateRange") + ${field.apiModelProperty}$!{field.dict} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum && $field.queryTypeEnum == "DateRange") + ${field.apiModelProperty} + private $field.javaType ${field.fieldName}Begin; + + ${field.apiModelProperty} + private $field.javaType ${field.fieldName}End; +#end +#end + +} diff --git a/yun-base/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm b/yun-base/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm new file mode 100644 index 0000000..15cbe9a --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm @@ -0,0 +1,30 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 更新表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}UpdateForm { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.notEmpty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/yun-base/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm b/yun-base/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm new file mode 100644 index 0000000..76ebd3d --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm @@ -0,0 +1,24 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 列表VO + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}VO { + +#foreach ($field in $fields) + + ${field.apiModelProperty}$!{field.notEmpty}$!{field.file} + private $field.javaType $field.fieldName; +#end + +} diff --git a/yun-base/src/main/resources/code-generator-template/java/manager/Manager.java.vm b/yun-base/src/main/resources/code-generator-template/java/manager/Manager.java.vm new file mode 100644 index 0000000..52811ca --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/manager/Manager.java.vm @@ -0,0 +1,21 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * ${basic.description} Manager + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ +@Service +public class ${name.upperCamel}Manager extends ServiceImpl<${name.upperCamel}Dao, ${name.upperCamel}Entity> { + + +} diff --git a/yun-base/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm b/yun-base/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm new file mode 100644 index 0000000..7a82712 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm @@ -0,0 +1,76 @@ + + + + + + + #foreach ($field in $fields) + ${tableName}.${field.columnName}#if($foreach.hasNext),#end + #end + + + + + +#if($deleteInfo.isSupportDelete) +### 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) +#if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + + update ${tableName} set deleted_flag = #{deletedFlag} + where ${primaryKeyColumnName} in + + #{item} + + +#end +#if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + + + update ${tableName} set deleted_flag = #{deletedFlag} + where ${primaryKeyColumnName} = #{${primaryKeyFieldName}} + +#end +#end +#end + + diff --git a/yun-base/src/main/resources/code-generator-template/java/service/Service.java.vm b/yun-base/src/main/resources/code-generator-template/java/service/Service.java.vm new file mode 100644 index 0000000..fe41c1f --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/service/Service.java.vm @@ -0,0 +1,100 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * ${basic.description} Service + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Service +public class ${name.upperCamel}Service { + + @Resource + private ${name.upperCamel}Dao ${name.lowerCamel}Dao; + + /** + * 分页查询 + */ + public PageResult<${name.upperCamel}VO> queryPage(${name.upperCamel}QueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List<${name.upperCamel}VO> list = ${name.lowerCamel}Dao.queryPage(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + +#if($insertAndUpdate.isSupportInsertAndUpdate) + /** + * 添加 + */ + public ResponseDTO add(${name.upperCamel}AddForm addForm) { + ${name.upperCamel}Entity ${name.lowerCamel}Entity = SmartBeanUtil.copy(addForm, ${name.upperCamel}Entity.class); + ${name.lowerCamel}Dao.insert(${name.lowerCamel}Entity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + */ + public ResponseDTO update(${name.upperCamel}UpdateForm updateForm) { + ${name.upperCamel}Entity ${name.lowerCamel}Entity = SmartBeanUtil.copy(updateForm, ${name.upperCamel}Entity.class); + ${name.lowerCamel}Dao.updateById(${name.lowerCamel}Entity); + return ResponseDTO.ok(); + } +#end + +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 批量删除 + */ + public ResponseDTO batchDelete(List<${primaryKeyJavaType}> idList) { + if (CollectionUtils.isEmpty(idList)){ + return ResponseDTO.ok(); + } + +### 真删除 or 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.batchUpdateDeleted(idList, true); +#else + ${name.lowerCamel}Dao.deleteBatchIds(idList); +#end + return ResponseDTO.ok(); + } + #end + + #if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 单个删除 + */ + public ResponseDTO delete(${primaryKeyJavaType} ${primaryKeyFieldName}) { + if (null == ${primaryKeyFieldName}){ + return ResponseDTO.ok(); + } + +### 真删除 or 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.updateDeleted(${primaryKeyFieldName}, true); +#end +#if(${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.deleteById(${primaryKeyFieldName}); +#end + return ResponseDTO.ok(); + } + #end +#end +} diff --git a/yun-base/src/main/resources/code-generator-template/java/sql/Menu.sql.vm b/yun-base/src/main/resources/code-generator-template/java/sql/Menu.sql.vm new file mode 100644 index 0000000..4f066e3 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/java/sql/Menu.sql.vm @@ -0,0 +1,22 @@ +# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下, +# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。 +# 如果你一切都是按照默认,那么下面的 SQL 基本不用改 + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id ) +VALUES ( '${basic.description}', 2, 0, '/${name.lowerHyphenCamel}/list', '/business/${name.lowerHyphenCamel}/${name.lowerHyphenCamel}-list.vue', false, false, true, false, 1, 1 ); + +# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID +SET @parent_id = NULL; +SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '${basic.description}'; + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '查询', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:query', '${name.lowerCamel}:query', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '添加', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:add', '${name.lowerCamel}:add', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '更新', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:update', '${name.lowerCamel}:update', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '删除', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:delete', '${name.lowerCamel}:delete', @parent_id, 1 ); diff --git a/yun-base/src/main/resources/code-generator-template/js/api.js.vm b/yun-base/src/main/resources/code-generator-template/js/api.js.vm new file mode 100644 index 0000000..b249d0c --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/js/api.js.vm @@ -0,0 +1,78 @@ +/** + * ${basic.description} api 封装 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ +import { postRequest, getRequest } from '/@/lib/axios'; + +export const ${name.lowerCamel}Api = { + + /** + * 分页查询 @author ${basic.frontAuthor} + */ + queryPage : (param) => { + return postRequest('/${name.lowerCamel}/queryPage', param); + }, + + /** + * 增加 @author ${basic.frontAuthor} + */ + add: (param) => { + return postRequest('/${name.lowerCamel}/add', param); + }, + + /** + * 修改 @author ${basic.frontAuthor} + */ + update: (param) => { + return postRequest('/${name.lowerCamel}/update', param); + }, +## ------------------ 详情 ------------------ + +#if($deleteInfo.isSupportDetail) + /** + * 获取详情 @author ${basic.frontAuthor} + */ + getDetail: (id) => { + return getRequest(`/${name.lowerCamel}/getDetail/\${id}`); + }, +#end + +## ------------------ 删除 ------------------ +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == 'Single') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + #end + #if($deleteInfo.deleteEnum == 'Batch') + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end + #if($deleteInfo.deleteEnum == 'SingleAndBatch') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end +#end + +}; diff --git a/yun-base/src/main/resources/code-generator-template/js/const.js.vm b/yun-base/src/main/resources/code-generator-template/js/const.js.vm new file mode 100644 index 0000000..30ca06a --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/js/const.js.vm @@ -0,0 +1,23 @@ +/** + * ${basic.description} 枚举 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ + +#foreach ($enum in $enumList) + +/** + * $enum.columnComment + */ +export const $enum.upperUnderscoreEnum = { + +} +#end + +export default { +#foreach ($enum in $enumList) + $enum.upperUnderscoreEnum, +#end +}; \ No newline at end of file diff --git a/yun-base/src/main/resources/code-generator-template/js/form.vue.vm b/yun-base/src/main/resources/code-generator-template/js/form.vue.vm new file mode 100644 index 0000000..501bc43 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/js/form.vue.vm @@ -0,0 +1,239 @@ + + + diff --git a/yun-base/src/main/resources/code-generator-template/js/list.vue.vm b/yun-base/src/main/resources/code-generator-template/js/list.vue.vm new file mode 100644 index 0000000..aecbbcb --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/js/list.vue.vm @@ -0,0 +1,348 @@ + + + diff --git a/yun-base/src/main/resources/code-generator-template/tools.xml b/yun-base/src/main/resources/code-generator-template/tools.xml new file mode 100644 index 0000000..bcfc8fe --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/tools.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/yun-base/src/main/resources/code-generator-template/ts/api.ts.vm b/yun-base/src/main/resources/code-generator-template/ts/api.ts.vm new file mode 100644 index 0000000..b249d0c --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/ts/api.ts.vm @@ -0,0 +1,78 @@ +/** + * ${basic.description} api 封装 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ +import { postRequest, getRequest } from '/@/lib/axios'; + +export const ${name.lowerCamel}Api = { + + /** + * 分页查询 @author ${basic.frontAuthor} + */ + queryPage : (param) => { + return postRequest('/${name.lowerCamel}/queryPage', param); + }, + + /** + * 增加 @author ${basic.frontAuthor} + */ + add: (param) => { + return postRequest('/${name.lowerCamel}/add', param); + }, + + /** + * 修改 @author ${basic.frontAuthor} + */ + update: (param) => { + return postRequest('/${name.lowerCamel}/update', param); + }, +## ------------------ 详情 ------------------ + +#if($deleteInfo.isSupportDetail) + /** + * 获取详情 @author ${basic.frontAuthor} + */ + getDetail: (id) => { + return getRequest(`/${name.lowerCamel}/getDetail/\${id}`); + }, +#end + +## ------------------ 删除 ------------------ +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == 'Single') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + #end + #if($deleteInfo.deleteEnum == 'Batch') + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end + #if($deleteInfo.deleteEnum == 'SingleAndBatch') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end +#end + +}; diff --git a/yun-base/src/main/resources/code-generator-template/ts/const.ts.vm b/yun-base/src/main/resources/code-generator-template/ts/const.ts.vm new file mode 100644 index 0000000..30ca06a --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/ts/const.ts.vm @@ -0,0 +1,23 @@ +/** + * ${basic.description} 枚举 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ + +#foreach ($enum in $enumList) + +/** + * $enum.columnComment + */ +export const $enum.upperUnderscoreEnum = { + +} +#end + +export default { +#foreach ($enum in $enumList) + $enum.upperUnderscoreEnum, +#end +}; \ No newline at end of file diff --git a/yun-base/src/main/resources/code-generator-template/ts/form.vue.vm b/yun-base/src/main/resources/code-generator-template/ts/form.vue.vm new file mode 100644 index 0000000..8438c91 --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/ts/form.vue.vm @@ -0,0 +1,239 @@ + + + diff --git a/yun-base/src/main/resources/code-generator-template/ts/list.vue.vm b/yun-base/src/main/resources/code-generator-template/ts/list.vue.vm new file mode 100644 index 0000000..1d55a2b --- /dev/null +++ b/yun-base/src/main/resources/code-generator-template/ts/list.vue.vm @@ -0,0 +1,348 @@ + + + diff --git a/yun-base/src/main/resources/dev/yun-base.yaml b/yun-base/src/main/resources/dev/yun-base.yaml new file mode 100644 index 0000000..d267c7c --- /dev/null +++ b/yun-base/src/main/resources/dev/yun-base.yaml @@ -0,0 +1,186 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useUnicode=true&connectionCollation=utf8mb4_general_ci + username: root + password: root + driver-class-name: com.p6spy.engine.spy.P6SpyDriver + initial-size: 2 + min-idle: 2 + max-active: 10 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: false + method: + pointcut: net.lab1024.sa..*Service.* + + # redis 连接池配置信息 + redis: + database: 1 + host: 127.0.0.1 + port: 6379 + password: + timeout: 10000ms + lettuce: + pool: + max-active: 5 + min-idle: 1 + max-idle: 3 + max-wait: 30000ms + + # 邮件,置以SSL的方式发送, 这个需要使用这种方式并且端口是465 + mail: + host: smtp.163.com + port: 465 + username: lab1024@163.com + password: LAB1024LAB + test-connection: false + properties: + mail: + smtp: + auth: true + ssl: + enable: true + socketFactory: + class: com.sun.mail.util.MailSSLSocketFactory + fallback: false + debug: false + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 上传文件和请求大小 + servlet: + multipart: + max-file-size: 20MB # 单个文件的最大大小 + max-request-size: 10MB # 整个请求的最大大小 + + # 缓存实现类型 + cache: + type: redis + +# 健康检查 +management: + endpoints: + web: + exposure: + include: health,info + health: + mail: + enabled: false + +# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) +server: + tomcat: + basedir: ${project.log-directory}/tomcat-logs + accesslog: + enabled: true + max-days: 7 + pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)" + +# 文件上传 配置 +file: + storage: + mode: local + local: + upload-path: /home/smart_admin_v3/upload/ #文件上传目录 + url-prefix: + cloud: + region: oss-cn-hangzhou + endpoint: oss-cn-hangzhou.aliyuncs.com + bucket-name: 1024lab-smart-admin + access-key: + secret-key: + url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + private-url-expire-seconds: 3600 + +# open api配置 +springdoc: + swagger-ui: + enabled: true # 开关 + doc-expansion: none #关闭展开 + tags-sorter: alpha + server-base-url: + api-docs: + enabled: true # 开关 +knife4j: + enable: true + basic: + enable: false + username: api # Basic认证用户名 + password: 1024 # Basic认证密码 + +# RestTemplate 请求配置 毫秒 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 300 + +# 热加载配置 +reload: + interval-seconds: 300 + +# sa-token 配置 +sa-token: + # token 名称(同时也是 cookie 名称) + token-name: Authorization + # token 前缀 例如:Bearer + token-prefix: Bearer + # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效 + timeout: 2592000 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: false + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false) + is-share: false + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用) + token-style: simple-uuid + # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + auto-renew: true + # 是否输出操作日志 + is-log: true + # 日志等级(trace、debug、info、warn、error、fatal) + log-level: debug + # 启动时的字符画打印 + is-print: false + # 是否从cookie读取token + is-read-cookie: false + +# SmartJob 定时任务配置(不需要可以直接删除以下配置,详细文档请看:https://www.xxxxxx.com) +smart: + job: + enabled: true + # 任务初始化延迟 默认30秒 可选 + init-delay: 10 + # 定时任务执行线程池数量 默认2 可选 + core-pool-size: 2 + # 数据库配置检测-开关 默认开启 可选(作用是固定间隔读取数据库配置更新任务,关闭后只能重启服务或通过接口修改定时任务,建议开启) + db-refresh-enabled: true + # 数据库配置检测-执行间隔 默认120秒 可选 + db-refresh-interval: 60 \ No newline at end of file diff --git a/yun-base/src/main/resources/ip2region.xdb b/yun-base/src/main/resources/ip2region.xdb new file mode 100644 index 0000000..9f6502b Binary files /dev/null and b/yun-base/src/main/resources/ip2region.xdb differ diff --git a/yun-base/src/main/resources/mapper/support/ChangeLogMapper.xml b/yun-base/src/main/resources/mapper/support/ChangeLogMapper.xml new file mode 100644 index 0000000..126951f --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/ChangeLogMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/CodeGeneratorMapper.xml b/yun-base/src/main/resources/mapper/support/CodeGeneratorMapper.xml new file mode 100644 index 0000000..de22935 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/CodeGeneratorMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/yun-base/src/main/resources/mapper/support/ConfigMapper.xml b/yun-base/src/main/resources/mapper/support/ConfigMapper.xml new file mode 100644 index 0000000..88882fe --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/ConfigMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/DataTracerMapper.xml b/yun-base/src/main/resources/mapper/support/DataTracerMapper.xml new file mode 100644 index 0000000..a713935 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/DataTracerMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/DictDataMapper.xml b/yun-base/src/main/resources/mapper/support/DictDataMapper.xml new file mode 100644 index 0000000..8397883 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/DictDataMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + diff --git a/yun-base/src/main/resources/mapper/support/DictMapper.xml b/yun-base/src/main/resources/mapper/support/DictMapper.xml new file mode 100644 index 0000000..ef58108 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/DictMapper.xml @@ -0,0 +1,45 @@ + + + + + + + t_dict.dict_id, + t_dict.dict_name, + t_dict.dict_code, + t_dict.remark, + t_dict.disabled_flag, + t_dict.create_time, + t_dict.update_time + + + + + + + + + diff --git a/yun-base/src/main/resources/mapper/support/FeedbackMapper.xml b/yun-base/src/main/resources/mapper/support/FeedbackMapper.xml new file mode 100644 index 0000000..1cc90cb --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/FeedbackMapper.xml @@ -0,0 +1,26 @@ + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/FileMapper.xml b/yun-base/src/main/resources/mapper/support/FileMapper.xml new file mode 100644 index 0000000..b53cd64 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/FileMapper.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/HeartBeatRecordMapper.xml b/yun-base/src/main/resources/mapper/support/HeartBeatRecordMapper.xml new file mode 100644 index 0000000..ce7100e --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/HeartBeatRecordMapper.xml @@ -0,0 +1,37 @@ + + + + + + + update t_heart_beat_record + set heart_beat_time = #{heartBeatTime} + + heart_beat_record_id = #{id} + + + + + + + + diff --git a/yun-base/src/main/resources/mapper/support/HelpDocDao.xml b/yun-base/src/main/resources/mapper/support/HelpDocDao.xml new file mode 100644 index 0000000..b55e7e2 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/HelpDocDao.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + update t_help_doc + set page_view_count = page_view_count + #{pageViewCountIncrease}, + user_view_count = user_view_count + #{userViewCountIncrease} + where help_doc_id = #{helpDocId} + + + + + + + + + + insert into t_help_doc_relation + (relation_id, relation_name, help_doc_id) + values + + ( #{item.relationId} ,#{item.relationName}, #{helpDocId} ) + + + + + delete + from t_help_doc_relation + where help_doc_id = #{helpDocId} + + + + + + + + insert into t_help_doc_view_record (help_doc_id, user_id,user_name, first_ip, first_user_agent, page_view_count) + values (#{helpDocId}, #{userId},#{userName}, #{ip}, #{userAgent}, #{pageViewCount}) + + + update t_help_doc_view_record + set page_view_count = page_view_count + 1, + last_ip = #{ip}, + last_user_agent = #{userAgent} + where help_doc_id = #{helpDocId} + and user_id = #{userId} + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/LoginFailMapper.xml b/yun-base/src/main/resources/mapper/support/LoginFailMapper.xml new file mode 100644 index 0000000..e41b9c6 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/LoginFailMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + delete + from t_login_fail + where user_id = #{userId} + and user_type = #{userType} + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/LoginLogMapper.xml b/yun-base/src/main/resources/mapper/support/LoginLogMapper.xml new file mode 100644 index 0000000..cffb1b6 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/LoginLogMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/MessageMapper.xml b/yun-base/src/main/resources/mapper/support/MessageMapper.xml new file mode 100644 index 0000000..2a3764c --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/MessageMapper.xml @@ -0,0 +1,56 @@ + + + + + + + UPDATE t_message + SET read_flag = #{readFlag}, + read_time = now() + WHERE message_id = #{messageId} + AND receiver_user_type = #{receiverUserType} + AND receiver_user_id = #{receiverUserId} + AND read_flag != #{readFlag} + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/OperateLogMapper.xml b/yun-base/src/main/resources/mapper/support/OperateLogMapper.xml new file mode 100644 index 0000000..ac987a6 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/OperateLogMapper.xml @@ -0,0 +1,45 @@ + + + + + + + + delete from t_operate_log where id in + + #{item} + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/PasswordLogMapper.xml b/yun-base/src/main/resources/mapper/support/PasswordLogMapper.xml new file mode 100644 index 0000000..84ef798 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/PasswordLogMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/ReloadItemMapper.xml b/yun-base/src/main/resources/mapper/support/ReloadItemMapper.xml new file mode 100644 index 0000000..40fea4c --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/ReloadItemMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/ReloadResultMapper.xml b/yun-base/src/main/resources/mapper/support/ReloadResultMapper.xml new file mode 100644 index 0000000..99a4fb9 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/ReloadResultMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/SerialNumberMapper.xml b/yun-base/src/main/resources/mapper/support/SerialNumberMapper.xml new file mode 100644 index 0000000..eba23ed --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/SerialNumberMapper.xml @@ -0,0 +1,21 @@ + + + + + + update t_serial_number + set + last_number = #{lastNumber}, + last_time = #{lastTime} + where + serial_number_id = #{serialNumberId} + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/SerialNumberRecordMapper.xml b/yun-base/src/main/resources/mapper/support/SerialNumberRecordMapper.xml new file mode 100644 index 0000000..b59fc53 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/SerialNumberRecordMapper.xml @@ -0,0 +1,32 @@ + + + + + + update t_serial_number_record + set last_number = #{lastNumber}, + count = count + #{count} + where + serial_number_id = #{serialNumberId} + and + record_date = #{recordDate} + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/SmartJobLogMapper.xml b/yun-base/src/main/resources/mapper/support/SmartJobLogMapper.xml new file mode 100644 index 0000000..48727dd --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/SmartJobLogMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/SmartJobMapper.xml b/yun-base/src/main/resources/mapper/support/SmartJobMapper.xml new file mode 100644 index 0000000..bd1ad56 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/SmartJobMapper.xml @@ -0,0 +1,43 @@ + + + + + + update t_smart_job + set deleted_flag = #{deletedFlag} + where job_id = #{jobId} + + + + + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/mapper/support/TableColumnMapper.xml b/yun-base/src/main/resources/mapper/support/TableColumnMapper.xml new file mode 100644 index 0000000..1f11c60 --- /dev/null +++ b/yun-base/src/main/resources/mapper/support/TableColumnMapper.xml @@ -0,0 +1,18 @@ + + + + + delete + from t_table_column + where user_id = #{userId} + and table_id = #{tableId} + + + + \ No newline at end of file diff --git a/yun-base/src/main/resources/pre/yun-base.yaml b/yun-base/src/main/resources/pre/yun-base.yaml new file mode 100644 index 0000000..98731e0 --- /dev/null +++ b/yun-base/src/main/resources/pre/yun-base.yaml @@ -0,0 +1,186 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: root + password: root + driver-class-name: com.p6spy.engine.spy.P6SpyDriver + initial-size: 2 + min-idle: 2 + max-active: 10 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: false + method: + pointcut: net.lab1024.sa..*Service.* + + # redis 连接池配置信息 + redis: + database: 1 + host: 127.0.0.1 + port: 6379 + password: + timeout: 10000ms + lettuce: + pool: + max-active: 5 + min-idle: 1 + max-idle: 3 + max-wait: 30000ms + + # 邮件,置以SSL的方式发送, 这个需要使用这种方式并且端口是465 + mail: + host: smtp.163.com + port: 465 + username: lab1024@163.com + password: LAB1024LAB + test-connection: false + properties: + mail: + smtp: + auth: true + ssl: + enable: true + socketFactory: + class: com.sun.mail.util.MailSSLSocketFactory + fallback: false + debug: false + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 上传文件和请求大小 + servlet: + multipart: + max-file-size: 20MB # 单个文件的最大大小 + max-request-size: 10MB # 整个请求的最大大小 + + # 缓存实现类型 + cache: + type: redis + +# 健康检查 +management: + endpoints: + web: + exposure: + include: health,info + health: + mail: + enabled: false + +# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) +server: + tomcat: + basedir: ${project.log-directory}/tomcat-logs + accesslog: + enabled: true + max-days: 7 + pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)" + +# 文件上传 配置 +file: + storage: + mode: local + local: + upload-path: /home/smart_admin_v3/upload/ #文件上传目录 + url-prefix: + cloud: + region: oss-cn-hangzhou + endpoint: oss-cn-hangzhou.aliyuncs.com + bucket-name: 1024lab-smart-admin + access-key: + secret-key: + url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + private-url-expire-seconds: 3600 + +# open api配置 +springdoc: + swagger-ui: + enabled: true # 开关 + doc-expansion: none #关闭展开 + tags-sorter: alpha + server-base-url: + api-docs: + enabled: true # 开关 +knife4j: + enable: true + basic: + enable: false + username: api # Basic认证用户名 + password: 1024 # Basic认证密码 + +# RestTemplate 请求配置 毫秒 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 300 + +# 热加载配置 +reload: + interval-seconds: 300 + +# sa-token 配置 +sa-token: + # token 名称(同时也是 cookie 名称) + token-name: Authorization + # token 前缀 例如:Bearer + token-prefix: Bearer + # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效 + timeout: 2592000 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: false + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false) + is-share: false + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用) + token-style: simple-uuid + # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + auto-renew: true + # 是否输出操作日志 + is-log: true + # 日志等级(trace、debug、info、warn、error、fatal) + log-level: debug + # 启动时的字符画打印 + is-print: false + # 是否从cookie读取token + is-read-cookie: false + +# SmartJob 定时任务配置(不需要可以直接删除以下配置,详细文档请看:https://www.xxxxxx.com) +smart: + job: + enabled: true + # 任务初始化延迟 默认30秒 可选 + init-delay: 10 + # 定时任务执行线程池数量 默认2 可选 + core-pool-size: 2 + # 数据库配置检测-开关 默认开启 可选(作用是固定间隔读取数据库配置更新任务,关闭后只能重启服务或通过接口修改定时任务,建议开启) + db-refresh-enabled: true + # 数据库配置检测-执行间隔 默认120秒 可选 + db-refresh-interval: 60 diff --git a/yun-base/src/main/resources/prod/yun-base.yaml b/yun-base/src/main/resources/prod/yun-base.yaml new file mode 100644 index 0000000..e724266 --- /dev/null +++ b/yun-base/src/main/resources/prod/yun-base.yaml @@ -0,0 +1,183 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: root + password: root + driver-class-name: com.mysql.cj.jdbc.Driver + initial-size: 10 + min-idle: 10 + max-active: 200 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: false + method: + pointcut: net.lab1024.sa..*Service.* + + # redis 连接池配置信息 + redis: + database: 1 + host: 127.0.0.1 + port: 6379 + password: + timeout: 10000ms + lettuce: + pool: + max-active: 100 + min-idle: 10 + max-idle: 50 + max-wait: 30000ms + # 邮件,置以SSL的方式发送, 这个需要使用这种方式并且端口是465 + mail: + host: smtp.163.com + port: 465 + username: lab1024@163.com + password: LAB1024LAB + test-connection: false + properties: + mail: + smtp: + auth: true + ssl: + enable: true + socketFactory: + class: com.sun.mail.util.MailSSLSocketFactory + fallback: false + debug: false + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 上传文件和请求大小 + servlet: + multipart: + max-file-size: 20MB # 单个文件的最大大小 + max-request-size: 10MB # 整个请求的最大大小 + + # 缓存实现类型 + cache: + type: redis + +# 健康检查 +management: + endpoints: + web: + exposure: + include: health,info + health: + mail: + enabled: false + +# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) +server: + tomcat: + basedir: ${project.log-directory}/tomcat-logs + accesslog: + enabled: true + max-days: 30 + pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)" + + +# 文件上传 配置 +file: + storage: + mode: local + local: + upload-path: /home/smart_admin_v3/upload/ #文件上传目录 + url-prefix: + cloud: + region: oss-cn-hangzhou + endpoint: oss-cn-hangzhou.aliyuncs.com + bucket-name: 1024lab-smart-admin + access-key: + secret-key: + url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + private-url-expire-seconds: 3600 + +# open api配置 +springdoc: + swagger-ui: + enabled: true # 开关 + doc-expansion: none #关闭展开 + tags-sorter: alpha + server-base-url: + api-docs: + enabled: true # 开关 +knife4j: + enable: true + basic: + enable: false + username: api # Basic认证用户名 + password: 1024 # Basic认证密码 + +# RestTemplate 请求配置 毫秒 +http: + pool: + max-total: 100 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# 心跳配置 +heart-beat: + interval-seconds: 60 + +# 热加载配置 +reload: + interval-seconds: 60 + +# sa-token 配置 +sa-token: + # token 名称(同时也是 cookie 名称) + token-name: Authorization + # token 前缀 例如:Bearer + token-prefix: Bearer + # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效 + timeout: 2592000 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: false + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false) + is-share: false + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用) + token-style: simple-uuid + # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + auto-renew: true + # 是否输出操作日志 + is-log: false + # 日志等级(trace、debug、info、warn、error、fatal) + log-level: warn + # 启动时的字符画打印 + is-print: false + # 是否从cookie读取token + is-read-cookie: false + +# SmartJob 定时任务配置(不需要可以直接删除以下配置,详细文档请看:https://www.xxxxxx.com) +smart: + job: + enabled: true + # 任务初始化延迟 默认30秒 可选 + init-delay: 10 + # 定时任务执行线程池数量 默认2 可选 + core-pool-size: 2 + # 数据库配置检测-开关 默认开启 可选(作用是固定间隔读取数据库配置更新任务,关闭后只能重启服务或通过接口修改定时任务,建议开启) + db-refresh-enabled: true + # 数据库配置检测-执行间隔 默认120秒 可选 + db-refresh-interval: 60 \ No newline at end of file diff --git a/yun-base/src/main/resources/test/yun-base.yaml b/yun-base/src/main/resources/test/yun-base.yaml new file mode 100644 index 0000000..98731e0 --- /dev/null +++ b/yun-base/src/main/resources/test/yun-base.yaml @@ -0,0 +1,186 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: root + password: root + driver-class-name: com.p6spy.engine.spy.P6SpyDriver + initial-size: 2 + min-idle: 2 + max-active: 10 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: false + method: + pointcut: net.lab1024.sa..*Service.* + + # redis 连接池配置信息 + redis: + database: 1 + host: 127.0.0.1 + port: 6379 + password: + timeout: 10000ms + lettuce: + pool: + max-active: 5 + min-idle: 1 + max-idle: 3 + max-wait: 30000ms + + # 邮件,置以SSL的方式发送, 这个需要使用这种方式并且端口是465 + mail: + host: smtp.163.com + port: 465 + username: lab1024@163.com + password: LAB1024LAB + test-connection: false + properties: + mail: + smtp: + auth: true + ssl: + enable: true + socketFactory: + class: com.sun.mail.util.MailSSLSocketFactory + fallback: false + debug: false + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 上传文件和请求大小 + servlet: + multipart: + max-file-size: 20MB # 单个文件的最大大小 + max-request-size: 10MB # 整个请求的最大大小 + + # 缓存实现类型 + cache: + type: redis + +# 健康检查 +management: + endpoints: + web: + exposure: + include: health,info + health: + mail: + enabled: false + +# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) +server: + tomcat: + basedir: ${project.log-directory}/tomcat-logs + accesslog: + enabled: true + max-days: 7 + pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)" + +# 文件上传 配置 +file: + storage: + mode: local + local: + upload-path: /home/smart_admin_v3/upload/ #文件上传目录 + url-prefix: + cloud: + region: oss-cn-hangzhou + endpoint: oss-cn-hangzhou.aliyuncs.com + bucket-name: 1024lab-smart-admin + access-key: + secret-key: + url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + private-url-expire-seconds: 3600 + +# open api配置 +springdoc: + swagger-ui: + enabled: true # 开关 + doc-expansion: none #关闭展开 + tags-sorter: alpha + server-base-url: + api-docs: + enabled: true # 开关 +knife4j: + enable: true + basic: + enable: false + username: api # Basic认证用户名 + password: 1024 # Basic认证密码 + +# RestTemplate 请求配置 毫秒 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 300 + +# 热加载配置 +reload: + interval-seconds: 300 + +# sa-token 配置 +sa-token: + # token 名称(同时也是 cookie 名称) + token-name: Authorization + # token 前缀 例如:Bearer + token-prefix: Bearer + # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效 + timeout: 2592000 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: false + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false) + is-share: false + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用) + token-style: simple-uuid + # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + auto-renew: true + # 是否输出操作日志 + is-log: true + # 日志等级(trace、debug、info、warn、error、fatal) + log-level: debug + # 启动时的字符画打印 + is-print: false + # 是否从cookie读取token + is-read-cookie: false + +# SmartJob 定时任务配置(不需要可以直接删除以下配置,详细文档请看:https://www.xxxxxx.com) +smart: + job: + enabled: true + # 任务初始化延迟 默认30秒 可选 + init-delay: 10 + # 定时任务执行线程池数量 默认2 可选 + core-pool-size: 2 + # 数据库配置检测-开关 默认开启 可选(作用是固定间隔读取数据库配置更新任务,关闭后只能重启服务或通过接口修改定时任务,建议开启) + db-refresh-enabled: true + # 数据库配置检测-执行间隔 默认120秒 可选 + db-refresh-interval: 60 diff --git a/yun-base/target/classes/META-INF/spring.factories b/yun-base/target/classes/META-INF/spring.factories new file mode 100644 index 0000000..7dc64b8 --- /dev/null +++ b/yun-base/target/classes/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.env.EnvironmentPostProcessor=\ + net.lab1024.sa.base.config.YamlProcessor \ No newline at end of file diff --git a/yun-base/target/classes/banner.txt b/yun-base/target/classes/banner.txt new file mode 100644 index 0000000..5e14f0d --- /dev/null +++ b/yun-base/target/classes/banner.txt @@ -0,0 +1,13 @@ + ${AnsiColor.BRIGHT_GREEN} + + / ____| | | /\ | | (_) +| (___ _ __ ___ __ _ _ __| |_ / \ __| |_ __ ___ _ _ __ + \___ \| '_ ` _ \ / _` | '__| __| / /\ \ / _` | '_ ` _ \| | '_ \ + ____) | | | | | | (_| | | | |_ / ____ \ (_| | | | | | | | | | | +|_____/|_| |_| |_|\__,_|_| \__/_/ \_\__,_|_| |_| |_|_|_| |_| + +保持谦逊 保持学习 ! +热爱代码 热爱生活 ! +永远年轻 永远前行 ! + +${AnsiColor.DEFAULT} \ No newline at end of file diff --git a/yun-base/target/classes/code-generator-template/java/constant/enum.java.vm b/yun-base/target/classes/code-generator-template/java/constant/enum.java.vm new file mode 100644 index 0000000..87c2c64 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/constant/enum.java.vm @@ -0,0 +1,24 @@ +package ${packageName}; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.base.common.enumeration.BaseEnum; + +/** + * ${enumDesc} + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@AllArgsConstructor +@Getter +public enum ${enumName} implements BaseEnum { + + ; + + private final ${enumJavaType} value; + + private final String desc; +} diff --git a/yun-base/target/classes/code-generator-template/java/controller/Controller.java.vm b/yun-base/target/classes/code-generator-template/java/controller/Controller.java.vm new file mode 100644 index 0000000..13ccc5b --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/controller/Controller.java.vm @@ -0,0 +1,75 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import cn.dev33.satoken.annotation.SaCheckPermission; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * ${basic.description} Controller + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@RestController +@Tag(name = "${basic.description}") +public class ${name.upperCamel}Controller { + + @Resource + private ${name.upperCamel}Service ${name.lowerCamel}Service; + + @Operation(summary = "分页查询 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/queryPage") + @SaCheckPermission("${name.lowerCamel}:query") + public ResponseDTO> queryPage(@RequestBody @Valid ${name.upperCamel}QueryForm queryForm) { + return ResponseDTO.ok(${name.lowerCamel}Service.queryPage(queryForm)); + } + +#if($insertAndUpdate.isSupportInsertAndUpdate) + @Operation(summary = "添加 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/add") + @SaCheckPermission("${name.lowerCamel}:add") + public ResponseDTO add(@RequestBody @Valid ${name.upperCamel}AddForm addForm) { + return ${name.lowerCamel}Service.add(addForm); + } + + @Operation(summary = "更新 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/update") + @SaCheckPermission("${name.lowerCamel}:update") + public ResponseDTO update(@RequestBody @Valid ${name.upperCamel}UpdateForm updateForm) { + return ${name.lowerCamel}Service.update(updateForm); + } +#end + +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + @Operation(summary = "批量删除 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/batchDelete") + @SaCheckPermission("${name.lowerCamel}:delete") + public ResponseDTO batchDelete(@RequestBody ValidateList<${primaryKeyJavaType}> idList) { + return ${name.lowerCamel}Service.batchDelete(idList); + } + #end + + #if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + @Operation(summary = "单个删除 @author ${basic.backendAuthor}") + @GetMapping("/${name.lowerCamel}/delete/{${primaryKeyFieldName}}") + @SaCheckPermission("${name.lowerCamel}:delete") + public ResponseDTO batchDelete(@PathVariable ${primaryKeyJavaType} ${primaryKeyFieldName}) { + return ${name.lowerCamel}Service.delete(${primaryKeyFieldName}); + } + #end +#end +} diff --git a/yun-base/target/classes/code-generator-template/java/dao/Dao.java.vm b/yun-base/target/classes/code-generator-template/java/dao/Dao.java.vm new file mode 100644 index 0000000..374c374 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/dao/Dao.java.vm @@ -0,0 +1,51 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * ${basic.description} Dao + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Mapper +public interface ${name.upperCamel}Dao extends BaseMapper<${name.upperCamel}Entity> { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List<${name.upperCamel}VO> queryPage(Page page, @Param("queryForm") ${name.upperCamel}QueryForm queryForm); + +#if($deleteInfo.isSupportDelete) +### 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) +#if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 更新删除状态 + */ + long updateDeleted(@Param("${primaryKeyFieldName}")${primaryKeyJavaType} ${primaryKeyFieldName},@Param("deletedFlag")boolean deletedFlag); + +#end +#if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 批量更新删除状态 + */ + void batchUpdateDeleted(@Param("idList")List<${primaryKeyJavaType}> idList,@Param("deletedFlag")boolean deletedFlag); + +#end +#end +#end +} diff --git a/yun-base/target/classes/code-generator-template/java/domain/entity/Entity.java.vm b/yun-base/target/classes/code-generator-template/java/domain/entity/Entity.java.vm new file mode 100644 index 0000000..146f9be --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/domain/entity/Entity.java.vm @@ -0,0 +1,38 @@ +package ${basic.javaPackageName}.domain.entity; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 实体类 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +@TableName("${tableName}") +public class ${name.upperCamel}Entity { +#foreach ($field in $fields) + + /** + * $field.columnComment + */ + #if($field.primaryKeyFlag && $field.autoIncreaseFlag) + @TableId(type = IdType.AUTO) + #end + #if($field.primaryKeyFlag && !$field.autoIncreaseFlag) + @TableId + #end + #if($field.columnName == "create_time") + @TableField(fill = FieldFill.INSERT) + #end + #if($field.columnName == "update_time") + @TableField(fill = FieldFill.INSERT_UPDATE) + #end + private $field.javaType $field.fieldName; +#end + +} diff --git a/yun-base/target/classes/code-generator-template/java/domain/form/AddForm.java.vm b/yun-base/target/classes/code-generator-template/java/domain/form/AddForm.java.vm new file mode 100644 index 0000000..d1e8581 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/domain/form/AddForm.java.vm @@ -0,0 +1,30 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 新建表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}AddForm { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.notEmpty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/yun-base/target/classes/code-generator-template/java/domain/form/QueryForm.java.vm b/yun-base/target/classes/code-generator-template/java/domain/form/QueryForm.java.vm new file mode 100644 index 0000000..69a247e --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/domain/form/QueryForm.java.vm @@ -0,0 +1,39 @@ +package ${packageName}; + +import net.lab1024.sa.base.common.domain.PageParam; +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 分页查询表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +@EqualsAndHashCode(callSuper = false) +public class ${name.upperCamel}QueryForm extends PageParam { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum && $field.queryTypeEnum != "DateRange") + ${field.apiModelProperty}$!{field.dict} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum && $field.queryTypeEnum == "DateRange") + ${field.apiModelProperty} + private $field.javaType ${field.fieldName}Begin; + + ${field.apiModelProperty} + private $field.javaType ${field.fieldName}End; +#end +#end + +} diff --git a/yun-base/target/classes/code-generator-template/java/domain/form/UpdateForm.java.vm b/yun-base/target/classes/code-generator-template/java/domain/form/UpdateForm.java.vm new file mode 100644 index 0000000..15cbe9a --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/domain/form/UpdateForm.java.vm @@ -0,0 +1,30 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 更新表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}UpdateForm { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.notEmpty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/yun-base/target/classes/code-generator-template/java/domain/vo/VO.java.vm b/yun-base/target/classes/code-generator-template/java/domain/vo/VO.java.vm new file mode 100644 index 0000000..76ebd3d --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/domain/vo/VO.java.vm @@ -0,0 +1,24 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 列表VO + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}VO { + +#foreach ($field in $fields) + + ${field.apiModelProperty}$!{field.notEmpty}$!{field.file} + private $field.javaType $field.fieldName; +#end + +} diff --git a/yun-base/target/classes/code-generator-template/java/manager/Manager.java.vm b/yun-base/target/classes/code-generator-template/java/manager/Manager.java.vm new file mode 100644 index 0000000..52811ca --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/manager/Manager.java.vm @@ -0,0 +1,21 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * ${basic.description} Manager + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ +@Service +public class ${name.upperCamel}Manager extends ServiceImpl<${name.upperCamel}Dao, ${name.upperCamel}Entity> { + + +} diff --git a/yun-base/target/classes/code-generator-template/java/mapper/Mapper.xml.vm b/yun-base/target/classes/code-generator-template/java/mapper/Mapper.xml.vm new file mode 100644 index 0000000..7a82712 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/mapper/Mapper.xml.vm @@ -0,0 +1,76 @@ + + + + + + + #foreach ($field in $fields) + ${tableName}.${field.columnName}#if($foreach.hasNext),#end + #end + + + + + +#if($deleteInfo.isSupportDelete) +### 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) +#if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + + update ${tableName} set deleted_flag = #{deletedFlag} + where ${primaryKeyColumnName} in + + #{item} + + +#end +#if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + + + update ${tableName} set deleted_flag = #{deletedFlag} + where ${primaryKeyColumnName} = #{${primaryKeyFieldName}} + +#end +#end +#end + + diff --git a/yun-base/target/classes/code-generator-template/java/service/Service.java.vm b/yun-base/target/classes/code-generator-template/java/service/Service.java.vm new file mode 100644 index 0000000..fe41c1f --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/service/Service.java.vm @@ -0,0 +1,100 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.domain.PageResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * ${basic.description} Service + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Service +public class ${name.upperCamel}Service { + + @Resource + private ${name.upperCamel}Dao ${name.lowerCamel}Dao; + + /** + * 分页查询 + */ + public PageResult<${name.upperCamel}VO> queryPage(${name.upperCamel}QueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List<${name.upperCamel}VO> list = ${name.lowerCamel}Dao.queryPage(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + +#if($insertAndUpdate.isSupportInsertAndUpdate) + /** + * 添加 + */ + public ResponseDTO add(${name.upperCamel}AddForm addForm) { + ${name.upperCamel}Entity ${name.lowerCamel}Entity = SmartBeanUtil.copy(addForm, ${name.upperCamel}Entity.class); + ${name.lowerCamel}Dao.insert(${name.lowerCamel}Entity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + */ + public ResponseDTO update(${name.upperCamel}UpdateForm updateForm) { + ${name.upperCamel}Entity ${name.lowerCamel}Entity = SmartBeanUtil.copy(updateForm, ${name.upperCamel}Entity.class); + ${name.lowerCamel}Dao.updateById(${name.lowerCamel}Entity); + return ResponseDTO.ok(); + } +#end + +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 批量删除 + */ + public ResponseDTO batchDelete(List<${primaryKeyJavaType}> idList) { + if (CollectionUtils.isEmpty(idList)){ + return ResponseDTO.ok(); + } + +### 真删除 or 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.batchUpdateDeleted(idList, true); +#else + ${name.lowerCamel}Dao.deleteBatchIds(idList); +#end + return ResponseDTO.ok(); + } + #end + + #if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 单个删除 + */ + public ResponseDTO delete(${primaryKeyJavaType} ${primaryKeyFieldName}) { + if (null == ${primaryKeyFieldName}){ + return ResponseDTO.ok(); + } + +### 真删除 or 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.updateDeleted(${primaryKeyFieldName}, true); +#end +#if(${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.deleteById(${primaryKeyFieldName}); +#end + return ResponseDTO.ok(); + } + #end +#end +} diff --git a/yun-base/target/classes/code-generator-template/java/sql/Menu.sql.vm b/yun-base/target/classes/code-generator-template/java/sql/Menu.sql.vm new file mode 100644 index 0000000..4f066e3 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/java/sql/Menu.sql.vm @@ -0,0 +1,22 @@ +# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下, +# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。 +# 如果你一切都是按照默认,那么下面的 SQL 基本不用改 + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id ) +VALUES ( '${basic.description}', 2, 0, '/${name.lowerHyphenCamel}/list', '/business/${name.lowerHyphenCamel}/${name.lowerHyphenCamel}-list.vue', false, false, true, false, 1, 1 ); + +# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID +SET @parent_id = NULL; +SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '${basic.description}'; + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '查询', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:query', '${name.lowerCamel}:query', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '添加', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:add', '${name.lowerCamel}:add', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '更新', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:update', '${name.lowerCamel}:update', @parent_id, 1 ); + +INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, api_perms, web_perms, context_menu_id, create_user_id ) +VALUES ( '删除', 3, @parent_id, false, false, true, false, 1, '${name.lowerCamel}:delete', '${name.lowerCamel}:delete', @parent_id, 1 ); diff --git a/yun-base/target/classes/code-generator-template/js/api.js.vm b/yun-base/target/classes/code-generator-template/js/api.js.vm new file mode 100644 index 0000000..b249d0c --- /dev/null +++ b/yun-base/target/classes/code-generator-template/js/api.js.vm @@ -0,0 +1,78 @@ +/** + * ${basic.description} api 封装 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ +import { postRequest, getRequest } from '/@/lib/axios'; + +export const ${name.lowerCamel}Api = { + + /** + * 分页查询 @author ${basic.frontAuthor} + */ + queryPage : (param) => { + return postRequest('/${name.lowerCamel}/queryPage', param); + }, + + /** + * 增加 @author ${basic.frontAuthor} + */ + add: (param) => { + return postRequest('/${name.lowerCamel}/add', param); + }, + + /** + * 修改 @author ${basic.frontAuthor} + */ + update: (param) => { + return postRequest('/${name.lowerCamel}/update', param); + }, +## ------------------ 详情 ------------------ + +#if($deleteInfo.isSupportDetail) + /** + * 获取详情 @author ${basic.frontAuthor} + */ + getDetail: (id) => { + return getRequest(`/${name.lowerCamel}/getDetail/\${id}`); + }, +#end + +## ------------------ 删除 ------------------ +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == 'Single') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + #end + #if($deleteInfo.deleteEnum == 'Batch') + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end + #if($deleteInfo.deleteEnum == 'SingleAndBatch') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end +#end + +}; diff --git a/yun-base/target/classes/code-generator-template/js/const.js.vm b/yun-base/target/classes/code-generator-template/js/const.js.vm new file mode 100644 index 0000000..30ca06a --- /dev/null +++ b/yun-base/target/classes/code-generator-template/js/const.js.vm @@ -0,0 +1,23 @@ +/** + * ${basic.description} 枚举 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ + +#foreach ($enum in $enumList) + +/** + * $enum.columnComment + */ +export const $enum.upperUnderscoreEnum = { + +} +#end + +export default { +#foreach ($enum in $enumList) + $enum.upperUnderscoreEnum, +#end +}; \ No newline at end of file diff --git a/yun-base/target/classes/code-generator-template/js/form.vue.vm b/yun-base/target/classes/code-generator-template/js/form.vue.vm new file mode 100644 index 0000000..501bc43 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/js/form.vue.vm @@ -0,0 +1,239 @@ + + + diff --git a/yun-base/target/classes/code-generator-template/js/list.vue.vm b/yun-base/target/classes/code-generator-template/js/list.vue.vm new file mode 100644 index 0000000..aecbbcb --- /dev/null +++ b/yun-base/target/classes/code-generator-template/js/list.vue.vm @@ -0,0 +1,348 @@ + + + diff --git a/yun-base/target/classes/code-generator-template/tools.xml b/yun-base/target/classes/code-generator-template/tools.xml new file mode 100644 index 0000000..bcfc8fe --- /dev/null +++ b/yun-base/target/classes/code-generator-template/tools.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/yun-base/target/classes/code-generator-template/ts/api.ts.vm b/yun-base/target/classes/code-generator-template/ts/api.ts.vm new file mode 100644 index 0000000..b249d0c --- /dev/null +++ b/yun-base/target/classes/code-generator-template/ts/api.ts.vm @@ -0,0 +1,78 @@ +/** + * ${basic.description} api 封装 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ +import { postRequest, getRequest } from '/@/lib/axios'; + +export const ${name.lowerCamel}Api = { + + /** + * 分页查询 @author ${basic.frontAuthor} + */ + queryPage : (param) => { + return postRequest('/${name.lowerCamel}/queryPage', param); + }, + + /** + * 增加 @author ${basic.frontAuthor} + */ + add: (param) => { + return postRequest('/${name.lowerCamel}/add', param); + }, + + /** + * 修改 @author ${basic.frontAuthor} + */ + update: (param) => { + return postRequest('/${name.lowerCamel}/update', param); + }, +## ------------------ 详情 ------------------ + +#if($deleteInfo.isSupportDetail) + /** + * 获取详情 @author ${basic.frontAuthor} + */ + getDetail: (id) => { + return getRequest(`/${name.lowerCamel}/getDetail/\${id}`); + }, +#end + +## ------------------ 删除 ------------------ +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == 'Single') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + #end + #if($deleteInfo.deleteEnum == 'Batch') + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end + #if($deleteInfo.deleteEnum == 'SingleAndBatch') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end +#end + +}; diff --git a/yun-base/target/classes/code-generator-template/ts/const.ts.vm b/yun-base/target/classes/code-generator-template/ts/const.ts.vm new file mode 100644 index 0000000..30ca06a --- /dev/null +++ b/yun-base/target/classes/code-generator-template/ts/const.ts.vm @@ -0,0 +1,23 @@ +/** + * ${basic.description} 枚举 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ + +#foreach ($enum in $enumList) + +/** + * $enum.columnComment + */ +export const $enum.upperUnderscoreEnum = { + +} +#end + +export default { +#foreach ($enum in $enumList) + $enum.upperUnderscoreEnum, +#end +}; \ No newline at end of file diff --git a/yun-base/target/classes/code-generator-template/ts/form.vue.vm b/yun-base/target/classes/code-generator-template/ts/form.vue.vm new file mode 100644 index 0000000..8438c91 --- /dev/null +++ b/yun-base/target/classes/code-generator-template/ts/form.vue.vm @@ -0,0 +1,239 @@ + + + diff --git a/yun-base/target/classes/code-generator-template/ts/list.vue.vm b/yun-base/target/classes/code-generator-template/ts/list.vue.vm new file mode 100644 index 0000000..1d55a2b --- /dev/null +++ b/yun-base/target/classes/code-generator-template/ts/list.vue.vm @@ -0,0 +1,348 @@ + + + diff --git a/yun-base/target/classes/ip2region.xdb b/yun-base/target/classes/ip2region.xdb new file mode 100644 index 0000000..9f6502b Binary files /dev/null and b/yun-base/target/classes/ip2region.xdb differ diff --git a/yun-base/target/classes/mapper/support/ChangeLogMapper.xml b/yun-base/target/classes/mapper/support/ChangeLogMapper.xml new file mode 100644 index 0000000..126951f --- /dev/null +++ b/yun-base/target/classes/mapper/support/ChangeLogMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/CodeGeneratorMapper.xml b/yun-base/target/classes/mapper/support/CodeGeneratorMapper.xml new file mode 100644 index 0000000..de22935 --- /dev/null +++ b/yun-base/target/classes/mapper/support/CodeGeneratorMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/yun-base/target/classes/mapper/support/ConfigMapper.xml b/yun-base/target/classes/mapper/support/ConfigMapper.xml new file mode 100644 index 0000000..88882fe --- /dev/null +++ b/yun-base/target/classes/mapper/support/ConfigMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/DataTracerMapper.xml b/yun-base/target/classes/mapper/support/DataTracerMapper.xml new file mode 100644 index 0000000..a713935 --- /dev/null +++ b/yun-base/target/classes/mapper/support/DataTracerMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/DictDataMapper.xml b/yun-base/target/classes/mapper/support/DictDataMapper.xml new file mode 100644 index 0000000..8397883 --- /dev/null +++ b/yun-base/target/classes/mapper/support/DictDataMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + diff --git a/yun-base/target/classes/mapper/support/DictMapper.xml b/yun-base/target/classes/mapper/support/DictMapper.xml new file mode 100644 index 0000000..ef58108 --- /dev/null +++ b/yun-base/target/classes/mapper/support/DictMapper.xml @@ -0,0 +1,45 @@ + + + + + + + t_dict.dict_id, + t_dict.dict_name, + t_dict.dict_code, + t_dict.remark, + t_dict.disabled_flag, + t_dict.create_time, + t_dict.update_time + + + + + + + + + diff --git a/yun-base/target/classes/mapper/support/FeedbackMapper.xml b/yun-base/target/classes/mapper/support/FeedbackMapper.xml new file mode 100644 index 0000000..1cc90cb --- /dev/null +++ b/yun-base/target/classes/mapper/support/FeedbackMapper.xml @@ -0,0 +1,26 @@ + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/FileMapper.xml b/yun-base/target/classes/mapper/support/FileMapper.xml new file mode 100644 index 0000000..b53cd64 --- /dev/null +++ b/yun-base/target/classes/mapper/support/FileMapper.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/HeartBeatRecordMapper.xml b/yun-base/target/classes/mapper/support/HeartBeatRecordMapper.xml new file mode 100644 index 0000000..ce7100e --- /dev/null +++ b/yun-base/target/classes/mapper/support/HeartBeatRecordMapper.xml @@ -0,0 +1,37 @@ + + + + + + + update t_heart_beat_record + set heart_beat_time = #{heartBeatTime} + + heart_beat_record_id = #{id} + + + + + + + + diff --git a/yun-base/target/classes/mapper/support/HelpDocDao.xml b/yun-base/target/classes/mapper/support/HelpDocDao.xml new file mode 100644 index 0000000..b55e7e2 --- /dev/null +++ b/yun-base/target/classes/mapper/support/HelpDocDao.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + update t_help_doc + set page_view_count = page_view_count + #{pageViewCountIncrease}, + user_view_count = user_view_count + #{userViewCountIncrease} + where help_doc_id = #{helpDocId} + + + + + + + + + + insert into t_help_doc_relation + (relation_id, relation_name, help_doc_id) + values + + ( #{item.relationId} ,#{item.relationName}, #{helpDocId} ) + + + + + delete + from t_help_doc_relation + where help_doc_id = #{helpDocId} + + + + + + + + insert into t_help_doc_view_record (help_doc_id, user_id,user_name, first_ip, first_user_agent, page_view_count) + values (#{helpDocId}, #{userId},#{userName}, #{ip}, #{userAgent}, #{pageViewCount}) + + + update t_help_doc_view_record + set page_view_count = page_view_count + 1, + last_ip = #{ip}, + last_user_agent = #{userAgent} + where help_doc_id = #{helpDocId} + and user_id = #{userId} + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/LoginFailMapper.xml b/yun-base/target/classes/mapper/support/LoginFailMapper.xml new file mode 100644 index 0000000..e41b9c6 --- /dev/null +++ b/yun-base/target/classes/mapper/support/LoginFailMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + delete + from t_login_fail + where user_id = #{userId} + and user_type = #{userType} + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/LoginLogMapper.xml b/yun-base/target/classes/mapper/support/LoginLogMapper.xml new file mode 100644 index 0000000..cffb1b6 --- /dev/null +++ b/yun-base/target/classes/mapper/support/LoginLogMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/MessageMapper.xml b/yun-base/target/classes/mapper/support/MessageMapper.xml new file mode 100644 index 0000000..2a3764c --- /dev/null +++ b/yun-base/target/classes/mapper/support/MessageMapper.xml @@ -0,0 +1,56 @@ + + + + + + + UPDATE t_message + SET read_flag = #{readFlag}, + read_time = now() + WHERE message_id = #{messageId} + AND receiver_user_type = #{receiverUserType} + AND receiver_user_id = #{receiverUserId} + AND read_flag != #{readFlag} + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/OperateLogMapper.xml b/yun-base/target/classes/mapper/support/OperateLogMapper.xml new file mode 100644 index 0000000..ac987a6 --- /dev/null +++ b/yun-base/target/classes/mapper/support/OperateLogMapper.xml @@ -0,0 +1,45 @@ + + + + + + + + delete from t_operate_log where id in + + #{item} + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/PasswordLogMapper.xml b/yun-base/target/classes/mapper/support/PasswordLogMapper.xml new file mode 100644 index 0000000..84ef798 --- /dev/null +++ b/yun-base/target/classes/mapper/support/PasswordLogMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/ReloadItemMapper.xml b/yun-base/target/classes/mapper/support/ReloadItemMapper.xml new file mode 100644 index 0000000..40fea4c --- /dev/null +++ b/yun-base/target/classes/mapper/support/ReloadItemMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/ReloadResultMapper.xml b/yun-base/target/classes/mapper/support/ReloadResultMapper.xml new file mode 100644 index 0000000..99a4fb9 --- /dev/null +++ b/yun-base/target/classes/mapper/support/ReloadResultMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/SerialNumberMapper.xml b/yun-base/target/classes/mapper/support/SerialNumberMapper.xml new file mode 100644 index 0000000..eba23ed --- /dev/null +++ b/yun-base/target/classes/mapper/support/SerialNumberMapper.xml @@ -0,0 +1,21 @@ + + + + + + update t_serial_number + set + last_number = #{lastNumber}, + last_time = #{lastTime} + where + serial_number_id = #{serialNumberId} + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/SerialNumberRecordMapper.xml b/yun-base/target/classes/mapper/support/SerialNumberRecordMapper.xml new file mode 100644 index 0000000..b59fc53 --- /dev/null +++ b/yun-base/target/classes/mapper/support/SerialNumberRecordMapper.xml @@ -0,0 +1,32 @@ + + + + + + update t_serial_number_record + set last_number = #{lastNumber}, + count = count + #{count} + where + serial_number_id = #{serialNumberId} + and + record_date = #{recordDate} + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/SmartJobLogMapper.xml b/yun-base/target/classes/mapper/support/SmartJobLogMapper.xml new file mode 100644 index 0000000..48727dd --- /dev/null +++ b/yun-base/target/classes/mapper/support/SmartJobLogMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/SmartJobMapper.xml b/yun-base/target/classes/mapper/support/SmartJobMapper.xml new file mode 100644 index 0000000..bd1ad56 --- /dev/null +++ b/yun-base/target/classes/mapper/support/SmartJobMapper.xml @@ -0,0 +1,43 @@ + + + + + + update t_smart_job + set deleted_flag = #{deletedFlag} + where job_id = #{jobId} + + + + + + + + \ No newline at end of file diff --git a/yun-base/target/classes/mapper/support/TableColumnMapper.xml b/yun-base/target/classes/mapper/support/TableColumnMapper.xml new file mode 100644 index 0000000..1f11c60 --- /dev/null +++ b/yun-base/target/classes/mapper/support/TableColumnMapper.xml @@ -0,0 +1,18 @@ + + + + + delete + from t_table_column + where user_id = #{userId} + and table_id = #{tableId} + + + + \ No newline at end of file diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/annoation/NoNeedLogin.class b/yun-base/target/classes/net/lab1024/sa/base/common/annoation/NoNeedLogin.class new file mode 100644 index 0000000..f29fa06 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/annoation/NoNeedLogin.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCode.class b/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCode.class new file mode 100644 index 0000000..1bf8d12 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCode.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCodeRangeContainer.class b/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCodeRangeContainer.class new file mode 100644 index 0000000..2bfe627 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCodeRangeContainer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCodeRegister.class b/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCodeRegister.class new file mode 100644 index 0000000..73061d6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/code/ErrorCodeRegister.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/code/SystemErrorCode.class b/yun-base/target/classes/net/lab1024/sa/base/common/code/SystemErrorCode.class new file mode 100644 index 0000000..e9d991c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/code/SystemErrorCode.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/code/UnexpectedErrorCode.class b/yun-base/target/classes/net/lab1024/sa/base/common/code/UnexpectedErrorCode.class new file mode 100644 index 0000000..79628c9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/code/UnexpectedErrorCode.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/code/UserErrorCode.class b/yun-base/target/classes/net/lab1024/sa/base/common/code/UserErrorCode.class new file mode 100644 index 0000000..6e3d1e1 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/code/UserErrorCode.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/constant/RequestHeaderConst.class b/yun-base/target/classes/net/lab1024/sa/base/common/constant/RequestHeaderConst.class new file mode 100644 index 0000000..42cb8f4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/constant/RequestHeaderConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/constant/StringConst.class b/yun-base/target/classes/net/lab1024/sa/base/common/constant/StringConst.class new file mode 100644 index 0000000..d75eeeb Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/constant/StringConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/controller/SupportBaseController.class b/yun-base/target/classes/net/lab1024/sa/base/common/controller/SupportBaseController.class new file mode 100644 index 0000000..d71e0a2 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/controller/SupportBaseController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/DataScopePlugin.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/DataScopePlugin.class new file mode 100644 index 0000000..0ba37e4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/DataScopePlugin.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageParam$SortItem.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageParam$SortItem.class new file mode 100644 index 0000000..2d25acd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageParam$SortItem.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageParam.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageParam.class new file mode 100644 index 0000000..8137320 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageParam.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageResult.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageResult.class new file mode 100644 index 0000000..3586efe Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/PageResult.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/RequestUrlVO.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/RequestUrlVO.class new file mode 100644 index 0000000..ac5aed6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/RequestUrlVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/RequestUser.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/RequestUser.class new file mode 100644 index 0000000..d70a660 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/RequestUser.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/ResponseDTO.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/ResponseDTO.class new file mode 100644 index 0000000..4ed4c65 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/ResponseDTO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/SystemEnvironment.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/SystemEnvironment.class new file mode 100644 index 0000000..334337e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/SystemEnvironment.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/UserPermission.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/UserPermission.class new file mode 100644 index 0000000..a99d59c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/UserPermission.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/ValidateData.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/ValidateData.class new file mode 100644 index 0000000..2daad70 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/ValidateData.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/domain/ValidateList.class b/yun-base/target/classes/net/lab1024/sa/base/common/domain/ValidateList.class new file mode 100644 index 0000000..92aa39e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/domain/ValidateList.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/BaseEnum$DeletedQuotationAware.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/BaseEnum$DeletedQuotationAware.class new file mode 100644 index 0000000..453c460 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/BaseEnum$DeletedQuotationAware.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/BaseEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/BaseEnum.class new file mode 100644 index 0000000..fd715f5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/BaseEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/DataTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/DataTypeEnum.class new file mode 100644 index 0000000..80e09e4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/DataTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/GenderEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/GenderEnum.class new file mode 100644 index 0000000..7bdaf63 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/GenderEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum$SystemEnvironmentNameConst.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum$SystemEnvironmentNameConst.class new file mode 100644 index 0000000..6c40dbd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum$SystemEnvironmentNameConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum.class new file mode 100644 index 0000000..4d239c5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/SystemEnvironmentEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/UserTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/UserTypeEnum.class new file mode 100644 index 0000000..fa5de52 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/enumeration/UserTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/exception/BusinessException.class b/yun-base/target/classes/net/lab1024/sa/base/common/exception/BusinessException.class new file mode 100644 index 0000000..0a91c83 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/exception/BusinessException.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/DictDataDeserializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/DictDataDeserializer.class new file mode 100644 index 0000000..36eba0d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/DictDataDeserializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/FileKeyVoDeserializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/FileKeyVoDeserializer.class new file mode 100644 index 0000000..98150e5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/FileKeyVoDeserializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/LongJsonDeserializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/LongJsonDeserializer.class new file mode 100644 index 0000000..c204a34 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/deserializer/LongJsonDeserializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/BigDecimalNullZeroSerializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/BigDecimalNullZeroSerializer.class new file mode 100644 index 0000000..dbdd88e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/BigDecimalNullZeroSerializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/DataMaskingSerializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/DataMaskingSerializer.class new file mode 100644 index 0000000..f00802d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/DataMaskingSerializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/FileKeySerializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/FileKeySerializer.class new file mode 100644 index 0000000..56a20c1 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/FileKeySerializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/FileKeyVoSerializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/FileKeyVoSerializer.class new file mode 100644 index 0000000..5c89437 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/FileKeyVoSerializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/LongJsonSerializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/LongJsonSerializer.class new file mode 100644 index 0000000..2158c7f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/LongJsonSerializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerialize.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerialize.class new file mode 100644 index 0000000..0f09821 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerialize.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerializer.class b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerializer.class new file mode 100644 index 0000000..dd8d77a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/json/serializer/enumeration/EnumSerializer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SchemaEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SchemaEnum.class new file mode 100644 index 0000000..e4a1087 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SchemaEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SchemaEnumPropertyCustomizer.class b/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SchemaEnumPropertyCustomizer.class new file mode 100644 index 0000000..99e3bd0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SchemaEnumPropertyCustomizer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SmartOperationCustomizer.class b/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SmartOperationCustomizer.class new file mode 100644 index 0000000..62459dd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/swagger/SmartOperationCustomizer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBeanUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBeanUtil.class new file mode 100644 index 0000000..a56fc91 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBeanUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBigDecimalUtil$Amount.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBigDecimalUtil$Amount.class new file mode 100644 index 0000000..61d9506 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBigDecimalUtil$Amount.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBigDecimalUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBigDecimalUtil.class new file mode 100644 index 0000000..6200ee8 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartBigDecimalUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartDateFormatterEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartDateFormatterEnum.class new file mode 100644 index 0000000..24c3515 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartDateFormatterEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartEnumUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartEnumUtil.class new file mode 100644 index 0000000..560d276 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartEnumUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil$CustomWaterMarkHandler.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil$CustomWaterMarkHandler.class new file mode 100644 index 0000000..d5b58c4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil$CustomWaterMarkHandler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil$Watermark.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil$Watermark.class new file mode 100644 index 0000000..1935984 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil$Watermark.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil.class new file mode 100644 index 0000000..9d5b6be Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartExcelUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartIpUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartIpUtil.class new file mode 100644 index 0000000..3207706 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartIpUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartLocalDateUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartLocalDateUtil.class new file mode 100644 index 0000000..4dd0cba Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartLocalDateUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartPageUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartPageUtil.class new file mode 100644 index 0000000..d5c7e5f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartPageUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartRequestUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartRequestUtil.class new file mode 100644 index 0000000..744ff57 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartRequestUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartResponseUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartResponseUtil.class new file mode 100644 index 0000000..997c974 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartResponseUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartStringUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartStringUtil.class new file mode 100644 index 0000000..0a07394 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartStringUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartVerificationUtil.class b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartVerificationUtil.class new file mode 100644 index 0000000..61e7db5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/util/SmartVerificationUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/validator/enumeration/CheckEnum.class b/yun-base/target/classes/net/lab1024/sa/base/common/validator/enumeration/CheckEnum.class new file mode 100644 index 0000000..3ab93fa Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/validator/enumeration/CheckEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/common/validator/enumeration/EnumValidator.class b/yun-base/target/classes/net/lab1024/sa/base/common/validator/enumeration/EnumValidator.class new file mode 100644 index 0000000..4a6008b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/common/validator/enumeration/EnumValidator.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig$AsyncExceptionConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig$AsyncExceptionConfig.class new file mode 100644 index 0000000..56d0a6c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig$AsyncExceptionConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig$AsyncExceptionHandler.class b/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig$AsyncExceptionHandler.class new file mode 100644 index 0000000..c1c9ebf Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig$AsyncExceptionHandler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig.class new file mode 100644 index 0000000..bdb2679 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/AsyncConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/CacheConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/CacheConfig.class new file mode 100644 index 0000000..e9bc495 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/CacheConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/CorsFilterConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/CorsFilterConfig.class new file mode 100644 index 0000000..9ffbb61 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/CorsFilterConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/DataSourceConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/DataSourceConfig.class new file mode 100644 index 0000000..55e9195 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/DataSourceConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/FileConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/FileConfig.class new file mode 100644 index 0000000..db0daa7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/FileConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/HeartBeatConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/HeartBeatConfig.class new file mode 100644 index 0000000..e13ab22 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/HeartBeatConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig$StringToLocalDate.class b/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig$StringToLocalDate.class new file mode 100644 index 0000000..50af000 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig$StringToLocalDate.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig$StringToLocalDateTime.class b/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig$StringToLocalDateTime.class new file mode 100644 index 0000000..f8bfac7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig$StringToLocalDateTime.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig.class new file mode 100644 index 0000000..e9c97aa Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/JsonConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/MybatisPlusConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/MybatisPlusConfig.class new file mode 100644 index 0000000..19dc37c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/MybatisPlusConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/RedisConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/RedisConfig.class new file mode 100644 index 0000000..a12da89 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/RedisConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/RepeatSubmitConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/RepeatSubmitConfig.class new file mode 100644 index 0000000..3b8081f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/RepeatSubmitConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/RestTemplateConfig$1.class b/yun-base/target/classes/net/lab1024/sa/base/config/RestTemplateConfig$1.class new file mode 100644 index 0000000..12a1f1c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/RestTemplateConfig$1.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/RestTemplateConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/RestTemplateConfig.class new file mode 100644 index 0000000..dcb3d7b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/RestTemplateConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/ScheduleConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/ScheduleConfig.class new file mode 100644 index 0000000..6f086cb Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/ScheduleConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/SwaggerConfig$1.class b/yun-base/target/classes/net/lab1024/sa/base/config/SwaggerConfig$1.class new file mode 100644 index 0000000..91f9d49 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/SwaggerConfig$1.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/SwaggerConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/SwaggerConfig.class new file mode 100644 index 0000000..06eff17 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/SwaggerConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/SystemEnvironmentConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/SystemEnvironmentConfig.class new file mode 100644 index 0000000..aa3c15e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/SystemEnvironmentConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/TokenConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/TokenConfig.class new file mode 100644 index 0000000..16efe76 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/TokenConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/UrlConfig.class b/yun-base/target/classes/net/lab1024/sa/base/config/UrlConfig.class new file mode 100644 index 0000000..f5f21b5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/UrlConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/config/YamlProcessor.class b/yun-base/target/classes/net/lab1024/sa/base/config/YamlProcessor.class new file mode 100644 index 0000000..1816678 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/config/YamlProcessor.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/CacheKeyConst$Dict.class b/yun-base/target/classes/net/lab1024/sa/base/constant/CacheKeyConst$Dict.class new file mode 100644 index 0000000..d882b6b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/CacheKeyConst$Dict.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/CacheKeyConst.class b/yun-base/target/classes/net/lab1024/sa/base/constant/CacheKeyConst.class new file mode 100644 index 0000000..092b485 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/CacheKeyConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/LoginDeviceEnum.class b/yun-base/target/classes/net/lab1024/sa/base/constant/LoginDeviceEnum.class new file mode 100644 index 0000000..474fb86 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/LoginDeviceEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/RedisKeyConst$Support.class b/yun-base/target/classes/net/lab1024/sa/base/constant/RedisKeyConst$Support.class new file mode 100644 index 0000000..f9b3389 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/RedisKeyConst$Support.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/RedisKeyConst.class b/yun-base/target/classes/net/lab1024/sa/base/constant/RedisKeyConst.class new file mode 100644 index 0000000..4c54215 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/RedisKeyConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/ReloadConst.class b/yun-base/target/classes/net/lab1024/sa/base/constant/ReloadConst.class new file mode 100644 index 0000000..e83c4fe Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/ReloadConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/SwaggerTagConst$Support.class b/yun-base/target/classes/net/lab1024/sa/base/constant/SwaggerTagConst$Support.class new file mode 100644 index 0000000..63211ed Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/SwaggerTagConst$Support.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/constant/SwaggerTagConst.class b/yun-base/target/classes/net/lab1024/sa/base/constant/SwaggerTagConst.class new file mode 100644 index 0000000..9b8b395 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/constant/SwaggerTagConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/handler/GlobalExceptionHandler.class b/yun-base/target/classes/net/lab1024/sa/base/handler/GlobalExceptionHandler.class new file mode 100644 index 0000000..f522bbd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/handler/GlobalExceptionHandler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/handler/MybatisPlusFillHandler.class b/yun-base/target/classes/net/lab1024/sa/base/handler/MybatisPlusFillHandler.class new file mode 100644 index 0000000..be114ac Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/handler/MybatisPlusFillHandler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/listener/Ip2RegionListener.class b/yun-base/target/classes/net/lab1024/sa/base/listener/Ip2RegionListener.class new file mode 100644 index 0000000..ffc240e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/listener/Ip2RegionListener.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/listener/LogVariableListener.class b/yun-base/target/classes/net/lab1024/sa/base/listener/LogVariableListener.class new file mode 100644 index 0000000..1eb1e65 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/listener/LogVariableListener.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/listener/WebServerListener.class b/yun-base/target/classes/net/lab1024/sa/base/listener/WebServerListener.class new file mode 100644 index 0000000..d647c88 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/listener/WebServerListener.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice$DecryptHttpInputMessage.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice$DecryptHttpInputMessage.class new file mode 100644 index 0000000..63f8e83 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice$DecryptHttpInputMessage.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice.class new file mode 100644 index 0000000..ea27fda Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/DecryptRequestAdvice.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/EncryptResponseAdvice.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/EncryptResponseAdvice.class new file mode 100644 index 0000000..031d4a4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/advice/EncryptResponseAdvice.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiDecrypt.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiDecrypt.class new file mode 100644 index 0000000..b4b4c76 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiDecrypt.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiEncrypt.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiEncrypt.class new file mode 100644 index 0000000..2c2f013 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/annotation/ApiEncrypt.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/domain/ApiEncryptForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/domain/ApiEncryptForm.class new file mode 100644 index 0000000..539df2b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/domain/ApiEncryptForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptService.class new file mode 100644 index 0000000..bec8d4f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceAesImpl.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceAesImpl.class new file mode 100644 index 0000000..af8a033 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceAesImpl.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceSmImpl.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceSmImpl.class new file mode 100644 index 0000000..6b9616d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/apiencrypt/service/ApiEncryptServiceSmImpl.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/CacheService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/CacheService.class new file mode 100644 index 0000000..c93e33c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/CacheService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/CaffeineCacheServiceImpl.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/CaffeineCacheServiceImpl.class new file mode 100644 index 0000000..1414074 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/CaffeineCacheServiceImpl.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/RedisCacheServiceImpl.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/RedisCacheServiceImpl.class new file mode 100644 index 0000000..6fedef6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/cache/RedisCacheServiceImpl.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/CaptchaController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/CaptchaController.class new file mode 100644 index 0000000..9803b05 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/CaptchaController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/CaptchaService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/CaptchaService.class new file mode 100644 index 0000000..4046ea3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/CaptchaService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/domain/CaptchaForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/domain/CaptchaForm.class new file mode 100644 index 0000000..c50b1b6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/domain/CaptchaForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/domain/CaptchaVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/domain/CaptchaVO.class new file mode 100644 index 0000000..1916751 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/captcha/domain/CaptchaVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/constant/ChangeLogTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/constant/ChangeLogTypeEnum.class new file mode 100644 index 0000000..9e4dcd4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/constant/ChangeLogTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/controller/ChangeLogController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/controller/ChangeLogController.class new file mode 100644 index 0000000..7bce3b4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/controller/ChangeLogController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/dao/ChangeLogDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/dao/ChangeLogDao.class new file mode 100644 index 0000000..d01239f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/dao/ChangeLogDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/entity/ChangeLogEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/entity/ChangeLogEntity.class new file mode 100644 index 0000000..7ea1228 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/entity/ChangeLogEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogAddForm.class new file mode 100644 index 0000000..7da9649 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogQueryForm.class new file mode 100644 index 0000000..7de911a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogUpdateForm.class new file mode 100644 index 0000000..fc50641 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/form/ChangeLogUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/vo/ChangeLogVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/vo/ChangeLogVO.class new file mode 100644 index 0000000..d4f6edc Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/domain/vo/ChangeLogVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/service/ChangeLogService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/service/ChangeLogService.class new file mode 100644 index 0000000..a8b37ec Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/changelog/service/ChangeLogService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeDeleteEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeDeleteEnum.class new file mode 100644 index 0000000..8051780 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeDeleteEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeFrontComponentEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeFrontComponentEnum.class new file mode 100644 index 0000000..a73746a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeFrontComponentEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorConstant.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorConstant.class new file mode 100644 index 0000000..26bbcdd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorConstant.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.class new file mode 100644 index 0000000..ec2eef4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.class new file mode 100644 index 0000000..08b6bad Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/controller/CodeGeneratorController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/controller/CodeGeneratorController.class new file mode 100644 index 0000000..723acc1 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/controller/CodeGeneratorController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorConfigDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorConfigDao.class new file mode 100644 index 0000000..2ddfc37 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorConfigDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorDao.class new file mode 100644 index 0000000..85d2027 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/dao/CodeGeneratorDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.class new file mode 100644 index 0000000..040e5df Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm$CodeGeneratorConfigFormBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm$CodeGeneratorConfigFormBuilder.class new file mode 100644 index 0000000..48e3183 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm$CodeGeneratorConfigFormBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.class new file mode 100644 index 0000000..dca5ba7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.class new file mode 100644 index 0000000..5706b89 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/TableQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/TableQueryForm.class new file mode 100644 index 0000000..bc82500 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/form/TableQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeBasic.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeBasic.class new file mode 100644 index 0000000..dd29b33 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeBasic.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeDelete.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeDelete.class new file mode 100644 index 0000000..f8a9d45 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeDelete.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeField.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeField.class new file mode 100644 index 0000000..b039e7d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeField.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdate.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdate.class new file mode 100644 index 0000000..5c6f84e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdate.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.class new file mode 100644 index 0000000..6e931f9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeQueryField.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeQueryField.class new file mode 100644 index 0000000..9365cfa Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeQueryField.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeTableField.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeTableField.class new file mode 100644 index 0000000..684e4de Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/model/CodeTableField.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableColumnVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableColumnVO.class new file mode 100644 index 0000000..2e65c16 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableColumnVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableConfigVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableConfigVO.class new file mode 100644 index 0000000..5fd756f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableConfigVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableVO.class new file mode 100644 index 0000000..331feb0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/domain/vo/TableVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorService.class new file mode 100644 index 0000000..6b680ad Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorTemplateService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorTemplateService.class new file mode 100644 index 0000000..023c9f9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/CodeGeneratorTemplateService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.class new file mode 100644 index 0000000..b576605 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ControllerVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ControllerVariableService.class new file mode 100644 index 0000000..b682efc Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ControllerVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/DaoVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/DaoVariableService.class new file mode 100644 index 0000000..38697ce Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/DaoVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ManagerVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ManagerVariableService.class new file mode 100644 index 0000000..3bbb39d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ManagerVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/MenuVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/MenuVariableService.class new file mode 100644 index 0000000..6dce551 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/MenuVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ServiceVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ServiceVariableService.class new file mode 100644 index 0000000..9c44915 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/ServiceVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.class new file mode 100644 index 0000000..a2ab2cb Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.class new file mode 100644 index 0000000..4f9e614 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.class new file mode 100644 index 0000000..a0e4aca Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.class new file mode 100644 index 0000000..d70a582 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.class new file mode 100644 index 0000000..a6f5a26 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/VOVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/VOVariableService.class new file mode 100644 index 0000000..70a387c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/backend/domain/VOVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ApiVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ApiVariableService.class new file mode 100644 index 0000000..76da33d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ApiVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ConstVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ConstVariableService.class new file mode 100644 index 0000000..96ec158 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ConstVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/FormVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/FormVariableService.class new file mode 100644 index 0000000..d1ebb3f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/FormVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ListVariableService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ListVariableService.class new file mode 100644 index 0000000..daf8059 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/service/variable/front/ListVariableService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/util/CodeGeneratorTool.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/util/CodeGeneratorTool.class new file mode 100644 index 0000000..bb1ee7f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/codegenerator/util/CodeGeneratorTool.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigController.class new file mode 100644 index 0000000..ac03f36 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigDao.class new file mode 100644 index 0000000..5347ca5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigKeyEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigKeyEnum.class new file mode 100644 index 0000000..2448532 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigKeyEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigService.class new file mode 100644 index 0000000..95721f3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/ConfigService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigAddForm.class new file mode 100644 index 0000000..7fa632d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigEntity.class new file mode 100644 index 0000000..4e316ad Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigQueryForm.class new file mode 100644 index 0000000..0f56d31 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigUpdateForm.class new file mode 100644 index 0000000..14f495c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigVO.class new file mode 100644 index 0000000..e337b73 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/config/domain/ConfigVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/DataMasking.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/DataMasking.class new file mode 100644 index 0000000..1041623 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/DataMasking.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/DataMaskingTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/DataMaskingTypeEnum.class new file mode 100644 index 0000000..a69e012 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/DataMaskingTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/SmartDataMaskingUtil.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/SmartDataMaskingUtil.class new file mode 100644 index 0000000..7e8fe7a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datamasking/SmartDataMaskingUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldBigDecimal.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldBigDecimal.class new file mode 100644 index 0000000..b5d916f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldBigDecimal.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldDict.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldDict.class new file mode 100644 index 0000000..8279ee9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldDict.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldEnum.class new file mode 100644 index 0000000..3d68f64 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldLabel.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldLabel.class new file mode 100644 index 0000000..f9ac186 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldLabel.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldSql.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldSql.class new file mode 100644 index 0000000..4a2e956 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/annoation/DataTracerFieldSql.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerConst.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerConst.class new file mode 100644 index 0000000..aad6756 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerTypeEnum.class new file mode 100644 index 0000000..c69e58e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/constant/DataTracerTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/controller/DataTracerController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/controller/DataTracerController.class new file mode 100644 index 0000000..4d2625f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/controller/DataTracerController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/dao/DataTracerDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/dao/DataTracerDao.class new file mode 100644 index 0000000..8e4417c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/dao/DataTracerDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/bo/DataTracerContentBO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/bo/DataTracerContentBO.class new file mode 100644 index 0000000..f4773b6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/bo/DataTracerContentBO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/entity/DataTracerEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/entity/DataTracerEntity.class new file mode 100644 index 0000000..f2a33ea Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/entity/DataTracerEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm$DataTracerFormBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm$DataTracerFormBuilder.class new file mode 100644 index 0000000..03290ff Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm$DataTracerFormBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm.class new file mode 100644 index 0000000..60ce57e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerQueryForm.class new file mode 100644 index 0000000..31c08a0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/form/DataTracerQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/vo/DataTracerVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/vo/DataTracerVO.class new file mode 100644 index 0000000..8a6416b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/domain/vo/DataTracerVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/manager/DataTracerManger.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/manager/DataTracerManger.class new file mode 100644 index 0000000..aeaced4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/manager/DataTracerManger.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/service/DataTracerChangeContentService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/service/DataTracerChangeContentService.class new file mode 100644 index 0000000..7d853e3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/service/DataTracerChangeContentService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/service/DataTracerService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/service/DataTracerService.class new file mode 100644 index 0000000..2da7e52 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/datatracer/service/DataTracerService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/dao/DictDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/dao/DictDao.class new file mode 100644 index 0000000..0651f2d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/dao/DictDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/dao/DictDataDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/dao/DictDataDao.class new file mode 100644 index 0000000..bb46cc7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/dao/DictDataDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/entity/DictDataEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/entity/DictDataEntity.class new file mode 100644 index 0000000..58d03c5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/entity/DictDataEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/entity/DictEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/entity/DictEntity.class new file mode 100644 index 0000000..9336d0b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/entity/DictEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictAddForm.class new file mode 100644 index 0000000..a127ee3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictDataAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictDataAddForm.class new file mode 100644 index 0000000..53a5bed Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictDataAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictDataUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictDataUpdateForm.class new file mode 100644 index 0000000..612643d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictDataUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictQueryForm.class new file mode 100644 index 0000000..0fd32ca Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictUpdateForm.class new file mode 100644 index 0000000..e08157f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/form/DictUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/vo/DictDataVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/vo/DictDataVO.class new file mode 100644 index 0000000..bc4b1f7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/vo/DictDataVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/vo/DictVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/vo/DictVO.class new file mode 100644 index 0000000..34148ac Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/domain/vo/DictVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/manager/DictManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/manager/DictManager.class new file mode 100644 index 0000000..1206b15 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/manager/DictManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/service/DictService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/service/DictService.class new file mode 100644 index 0000000..c972bc9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/dict/service/DictService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/controller/FeedbackController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/controller/FeedbackController.class new file mode 100644 index 0000000..7294fe0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/controller/FeedbackController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/dao/FeedbackDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/dao/FeedbackDao.class new file mode 100644 index 0000000..70b07dc Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/dao/FeedbackDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackAddForm.class new file mode 100644 index 0000000..6939904 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackEntity.class new file mode 100644 index 0000000..61126ff Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackQueryForm.class new file mode 100644 index 0000000..ec4b3dd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackVO.class new file mode 100644 index 0000000..a73fd78 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/domain/FeedbackVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/service/FeedbackService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/service/FeedbackService.class new file mode 100644 index 0000000..c96aaef Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/feedback/service/FeedbackService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/constant/FileFolderTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/constant/FileFolderTypeEnum.class new file mode 100644 index 0000000..bdd076a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/constant/FileFolderTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/controller/FileController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/controller/FileController.class new file mode 100644 index 0000000..be4a3b6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/controller/FileController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/dao/FileDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/dao/FileDao.class new file mode 100644 index 0000000..badbd36 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/dao/FileDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/entity/FileEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/entity/FileEntity.class new file mode 100644 index 0000000..caeed7c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/entity/FileEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/form/FileQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/form/FileQueryForm.class new file mode 100644 index 0000000..4da4a54 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/form/FileQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/form/FileUrlUploadForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/form/FileUrlUploadForm.class new file mode 100644 index 0000000..d338e51 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/form/FileUrlUploadForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileDownloadVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileDownloadVO.class new file mode 100644 index 0000000..e4f9dcf Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileDownloadVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileMetadataVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileMetadataVO.class new file mode 100644 index 0000000..4198131 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileMetadataVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileUploadVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileUploadVO.class new file mode 100644 index 0000000..39fa426 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileUploadVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileVO.class new file mode 100644 index 0000000..35aea08 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/domain/vo/FileVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileService.class new file mode 100644 index 0000000..e223960 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileStorageCloudServiceImpl.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileStorageCloudServiceImpl.class new file mode 100644 index 0000000..cafa9a7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileStorageCloudServiceImpl.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileStorageLocalServiceImpl.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileStorageLocalServiceImpl.class new file mode 100644 index 0000000..0551d82 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/FileStorageLocalServiceImpl.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/IFileStorageService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/IFileStorageService.class new file mode 100644 index 0000000..88e065d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/file/service/IFileStorageService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordDao.class new file mode 100644 index 0000000..67424ab Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordHandler.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordHandler.class new file mode 100644 index 0000000..0cc9286 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatRecordHandler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatService.class new file mode 100644 index 0000000..c4d2cad Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/HeartBeatService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatManager.class new file mode 100644 index 0000000..9ea2e6e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRecord.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRecord.class new file mode 100644 index 0000000..f994ee0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRecord.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRunnable.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRunnable.class new file mode 100644 index 0000000..cd49b0e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/HeartBeatRunnable.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/IHeartBeatRecordHandler.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/IHeartBeatRecordHandler.class new file mode 100644 index 0000000..35c647f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/core/IHeartBeatRecordHandler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordEntity.class new file mode 100644 index 0000000..2bd5238 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordQueryForm.class new file mode 100644 index 0000000..0c6b3d6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordVO.class new file mode 100644 index 0000000..4b4b5c9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/heartbeat/domain/HeartBeatRecordVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/controller/HelpDocController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/controller/HelpDocController.class new file mode 100644 index 0000000..d22d4e6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/controller/HelpDocController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocCatalogDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocCatalogDao.class new file mode 100644 index 0000000..b743e15 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocCatalogDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocDao.class new file mode 100644 index 0000000..bc13dd5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/dao/HelpDocDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity$HelpDocCatalogEntityBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity$HelpDocCatalogEntityBuilder.class new file mode 100644 index 0000000..8a05a3f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity$HelpDocCatalogEntityBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.class new file mode 100644 index 0000000..cfe9e7d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocEntity.class new file mode 100644 index 0000000..556f426 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/entity/HelpDocEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocAddForm.class new file mode 100644 index 0000000..0551508 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.class new file mode 100644 index 0000000..8204fab Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.class new file mode 100644 index 0000000..7a99ab9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocQueryForm.class new file mode 100644 index 0000000..bdaf714 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocRelationForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocRelationForm.class new file mode 100644 index 0000000..d7c5172 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocRelationForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocUpdateForm.class new file mode 100644 index 0000000..93402a0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.class new file mode 100644 index 0000000..ec10b9f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocCatalogVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocCatalogVO.class new file mode 100644 index 0000000..2962e07 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocCatalogVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocDetailVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocDetailVO.class new file mode 100644 index 0000000..01e3066 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocDetailVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRecordVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRecordVO.class new file mode 100644 index 0000000..f67d4b0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRecordVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRelationVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRelationVO.class new file mode 100644 index 0000000..0ec329a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocRelationVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocVO.class new file mode 100644 index 0000000..0690df0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.class new file mode 100644 index 0000000..91caad6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/manager/HelpDocManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/manager/HelpDocManager.class new file mode 100644 index 0000000..70bcbdd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/manager/HelpDocManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocCatalogService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocCatalogService.class new file mode 100644 index 0000000..a5d2a6d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocCatalogService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocService.class new file mode 100644 index 0000000..be467a6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocUserService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocUserService.class new file mode 100644 index 0000000..6ed51f3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/helpdoc/service/HelpDocUserService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager$SmartJobMsgListener.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager$SmartJobMsgListener.class new file mode 100644 index 0000000..bb7324b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager$SmartJobMsgListener.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager.class new file mode 100644 index 0000000..2b975a8 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobClientManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobService.class new file mode 100644 index 0000000..85f1324 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/SmartJobService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobAddForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobAddForm.class new file mode 100644 index 0000000..9029ba3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobAddForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobEnabledUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobEnabledUpdateForm.class new file mode 100644 index 0000000..d308f2f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobEnabledUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobExecuteForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobExecuteForm.class new file mode 100644 index 0000000..9f9d515 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobExecuteForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogQueryForm.class new file mode 100644 index 0000000..ad356c7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogVO.class new file mode 100644 index 0000000..3ab0896 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobLogVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg$MsgTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg$MsgTypeEnum.class new file mode 100644 index 0000000..98205bd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg$MsgTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg.class new file mode 100644 index 0000000..ef5e057 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobMsg.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobQueryForm.class new file mode 100644 index 0000000..b4e9561 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobUpdateForm.class new file mode 100644 index 0000000..76cee26 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobUpdateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobVO.class new file mode 100644 index 0000000..d1ae083 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/api/domain/SmartJobVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/config/SmartJobAutoConfiguration.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/config/SmartJobAutoConfiguration.class new file mode 100644 index 0000000..f95602a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/config/SmartJobAutoConfiguration.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/config/SmartJobConfig.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/config/SmartJobConfig.class new file mode 100644 index 0000000..d7def57 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/config/SmartJobConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobConst.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobConst.class new file mode 100644 index 0000000..6816ea5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobConst.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobTriggerTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobTriggerTypeEnum.class new file mode 100644 index 0000000..499aa0d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobTriggerTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobUtil.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobUtil.class new file mode 100644 index 0000000..befb9b8 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/constant/SmartJobUtil.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJob.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJob.class new file mode 100644 index 0000000..fe74ea1 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJob.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobExecutor.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobExecutor.class new file mode 100644 index 0000000..5a06a56 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobExecutor.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobLauncher.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobLauncher.class new file mode 100644 index 0000000..2085cf0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobLauncher.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobScheduler.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobScheduler.class new file mode 100644 index 0000000..cf75ff1 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/core/SmartJobScheduler.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobDao.class new file mode 100644 index 0000000..8680b75 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobLogDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobLogDao.class new file mode 100644 index 0000000..aeb5ddf Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobLogDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobRepository.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobRepository.class new file mode 100644 index 0000000..fe9cacd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/SmartJobRepository.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobEntity.class new file mode 100644 index 0000000..0dcfc1e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobLogEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobLogEntity.class new file mode 100644 index 0000000..fd028d0 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/repository/domain/SmartJobLogEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/SmartJobSample1.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/SmartJobSample1.class new file mode 100644 index 0000000..df4fc7c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/SmartJobSample1.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/SmartJobSample2.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/SmartJobSample2.class new file mode 100644 index 0000000..9300048 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/SmartJobSample2.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/package-info.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/package-info.class new file mode 100644 index 0000000..5c279a3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/job/sample/package-info.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogDao.class new file mode 100644 index 0000000..9353b7c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogResultEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogResultEnum.class new file mode 100644 index 0000000..9f3ef8e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogResultEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogService.class new file mode 100644 index 0000000..6347771 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/LoginLogService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity$LoginLogEntityBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity$LoginLogEntityBuilder.class new file mode 100644 index 0000000..4b6952f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity$LoginLogEntityBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity.class new file mode 100644 index 0000000..ba83a0a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogQueryForm.class new file mode 100644 index 0000000..04259c8 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogVO.class new file mode 100644 index 0000000..5882059 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/loginlog/domain/LoginLogVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/MailService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/MailService.class new file mode 100644 index 0000000..e8b6072 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/MailService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/MailTemplateDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/MailTemplateDao.class new file mode 100644 index 0000000..b66bf4b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/MailTemplateDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/constant/MailTemplateCodeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/constant/MailTemplateCodeEnum.class new file mode 100644 index 0000000..112be1f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/constant/MailTemplateCodeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/constant/MailTemplateTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/constant/MailTemplateTypeEnum.class new file mode 100644 index 0000000..03d0c15 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/constant/MailTemplateTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/domain/MailTemplateEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/domain/MailTemplateEntity.class new file mode 100644 index 0000000..e811628 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/mail/domain/MailTemplateEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/constant/MessageTemplateEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/constant/MessageTemplateEnum.class new file mode 100644 index 0000000..57bffe6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/constant/MessageTemplateEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/constant/MessageTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/constant/MessageTypeEnum.class new file mode 100644 index 0000000..e09b954 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/constant/MessageTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/controller/MessageController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/controller/MessageController.class new file mode 100644 index 0000000..b4e8275 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/controller/MessageController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/dao/MessageDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/dao/MessageDao.class new file mode 100644 index 0000000..0c05e6e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/dao/MessageDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageEntity.class new file mode 100644 index 0000000..3c725bb Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageQueryForm.class new file mode 100644 index 0000000..ca90296 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageSendForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageSendForm.class new file mode 100644 index 0000000..55a4cc9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageSendForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageTemplateSendForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageTemplateSendForm.class new file mode 100644 index 0000000..908cb37 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageTemplateSendForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageVO.class new file mode 100644 index 0000000..46327fd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/domain/MessageVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/service/MessageManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/service/MessageManager.class new file mode 100644 index 0000000..22cae9f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/service/MessageManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/message/service/MessageService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/service/MessageService.class new file mode 100644 index 0000000..6d491ad Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/message/service/MessageService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/OperateLogDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/OperateLogDao.class new file mode 100644 index 0000000..97115b9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/OperateLogDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/OperateLogService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/OperateLogService.class new file mode 100644 index 0000000..3f933a7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/OperateLogService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/annotation/OperateLog.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/annotation/OperateLog.class new file mode 100644 index 0000000..cc31c77 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/annotation/OperateLog.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogAspect.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogAspect.class new file mode 100644 index 0000000..b3b3fc5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogAspect.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig$OperateLogConfigBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig$OperateLogConfigBuilder.class new file mode 100644 index 0000000..df0e92b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig$OperateLogConfigBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig.class new file mode 100644 index 0000000..9906cd2 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/core/OperateLogConfig.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity$OperateLogEntityBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity$OperateLogEntityBuilder.class new file mode 100644 index 0000000..74d6c0c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity$OperateLogEntityBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity.class new file mode 100644 index 0000000..85e0f84 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogQueryForm.class new file mode 100644 index 0000000..8e51e99 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogVO.class new file mode 100644 index 0000000..8648bb4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/operatelog/domain/OperateLogVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/CustomRedisCacheManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/CustomRedisCacheManager.class new file mode 100644 index 0000000..3bc13de Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/CustomRedisCacheManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedisService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedisService.class new file mode 100644 index 0000000..64bad2a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedisService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedissonPasswordConfigurationCustomizer.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedissonPasswordConfigurationCustomizer.class new file mode 100644 index 0000000..9de6b1f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedissonPasswordConfigurationCustomizer.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedissonService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedissonService.class new file mode 100644 index 0000000..b4b1f91 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/redis/RedissonService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/ReloadCommand.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/ReloadCommand.class new file mode 100644 index 0000000..1a1acdf Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/ReloadCommand.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/ReloadService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/ReloadService.class new file mode 100644 index 0000000..22d5799 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/ReloadService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/AbstractSmartReloadCommand.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/AbstractSmartReloadCommand.class new file mode 100644 index 0000000..a82f667 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/AbstractSmartReloadCommand.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/SmartReloadManager.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/SmartReloadManager.class new file mode 100644 index 0000000..ad3f7e9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/SmartReloadManager.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/annoation/SmartReload.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/annoation/SmartReload.class new file mode 100644 index 0000000..66006b6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/annoation/SmartReload.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadItem.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadItem.class new file mode 100644 index 0000000..ac26c88 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadItem.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadObject.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadObject.class new file mode 100644 index 0000000..b702ef6 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadObject.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadResult.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadResult.class new file mode 100644 index 0000000..1b21188 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/domain/SmartReloadResult.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/thread/SmartReloadRunnable.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/thread/SmartReloadRunnable.class new file mode 100644 index 0000000..5ddf18e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/core/thread/SmartReloadRunnable.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/dao/ReloadItemDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/dao/ReloadItemDao.class new file mode 100644 index 0000000..01daa8e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/dao/ReloadItemDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/dao/ReloadResultDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/dao/ReloadResultDao.class new file mode 100644 index 0000000..87b9bf9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/dao/ReloadResultDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadForm.class new file mode 100644 index 0000000..9584ee4 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadItemEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadItemEntity.class new file mode 100644 index 0000000..9abbbd5 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadItemEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadItemVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadItemVO.class new file mode 100644 index 0000000..2f27092 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadItemVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadResultEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadResultEntity.class new file mode 100644 index 0000000..e307db2 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadResultEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadResultVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadResultVO.class new file mode 100644 index 0000000..23677f2 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/reload/domain/ReloadResultVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/RepeatSubmitAspect.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/RepeatSubmitAspect.class new file mode 100644 index 0000000..7516b4d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/RepeatSubmitAspect.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/annoation/RepeatSubmit.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/annoation/RepeatSubmit.class new file mode 100644 index 0000000..ae1b79b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/annoation/RepeatSubmit.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.class new file mode 100644 index 0000000..2c6c905 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitMemoryTicket.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitMemoryTicket.class new file mode 100644 index 0000000..25586f8 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitMemoryTicket.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.class new file mode 100644 index 0000000..803deda Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/dao/LoginFailDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/dao/LoginFailDao.class new file mode 100644 index 0000000..e71a31d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/dao/LoginFailDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/dao/PasswordLogDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/dao/PasswordLogDao.class new file mode 100644 index 0000000..293dc1d Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/dao/PasswordLogDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/Level3ProtectConfigForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/Level3ProtectConfigForm.class new file mode 100644 index 0000000..58cfece Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/Level3ProtectConfigForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity$LoginFailEntityBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity$LoginFailEntityBuilder.class new file mode 100644 index 0000000..61fa6b9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity$LoginFailEntityBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity.class new file mode 100644 index 0000000..c44d42f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailQueryForm.class new file mode 100644 index 0000000..1e34222 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailVO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailVO.class new file mode 100644 index 0000000..89af923 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/LoginFailVO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/PasswordLogEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/PasswordLogEntity.class new file mode 100644 index 0000000..70fad1a Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/domain/PasswordLogEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/Level3ProtectConfigService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/Level3ProtectConfigService.class new file mode 100644 index 0000000..88c9f75 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/Level3ProtectConfigService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityFileService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityFileService.class new file mode 100644 index 0000000..2e57017 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityFileService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityLoginService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityLoginService.class new file mode 100644 index 0000000..20b42ff Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityLoginService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityPasswordService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityPasswordService.class new file mode 100644 index 0000000..833ec78 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/securityprotect/service/SecurityPasswordService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberIdEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberIdEnum.class new file mode 100644 index 0000000..7ed3068 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberIdEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.class new file mode 100644 index 0000000..06ad955 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberDao.class new file mode 100644 index 0000000..9ead74c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberRecordDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberRecordDao.class new file mode 100644 index 0000000..f820e90 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/dao/SerialNumberRecordDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberEntity.class new file mode 100644 index 0000000..4cfaba7 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateForm.class new file mode 100644 index 0000000..f40bb0c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO$SerialNumberGenerateResultBOBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO$SerialNumberGenerateResultBOBuilder.class new file mode 100644 index 0000000..3ef360f Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO$SerialNumberGenerateResultBOBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO.class new file mode 100644 index 0000000..b2f49d9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberGenerateResultBO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO$SerialNumberInfoBOBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO$SerialNumberInfoBOBuilder.class new file mode 100644 index 0000000..ba5a383 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO$SerialNumberInfoBOBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO.class new file mode 100644 index 0000000..e920824 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberInfoBO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO$SerialNumberLastGenerateBOBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO$SerialNumberLastGenerateBOBuilder.class new file mode 100644 index 0000000..aa077dd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO$SerialNumberLastGenerateBOBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO.class new file mode 100644 index 0000000..e292188 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberLastGenerateBO.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity$SerialNumberRecordEntityBuilder.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity$SerialNumberRecordEntityBuilder.class new file mode 100644 index 0000000..9d282e8 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity$SerialNumberRecordEntityBuilder.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity.class new file mode 100644 index 0000000..0f7783e Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordQueryForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordQueryForm.class new file mode 100644 index 0000000..470cdd1 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/domain/SerialNumberRecordQueryForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberBaseService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberBaseService.class new file mode 100644 index 0000000..5676f97 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberBaseService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberRecordService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberRecordService.class new file mode 100644 index 0000000..5e4feff Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberRecordService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberService.class new file mode 100644 index 0000000..231e323 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/SerialNumberService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberInternService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberInternService.class new file mode 100644 index 0000000..ddb4324 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberInternService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberMysqlService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberMysqlService.class new file mode 100644 index 0000000..4e2555b Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberMysqlService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberRedisService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberRedisService.class new file mode 100644 index 0000000..d034057 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/serialnumber/service/impl/SerialNumberRedisService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnController.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnController.class new file mode 100644 index 0000000..0cf5c4c Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnController.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnDao.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnDao.class new file mode 100644 index 0000000..b11dae3 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnDao.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnService.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnService.class new file mode 100644 index 0000000..26a96cc Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/TableColumnService.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnEntity.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnEntity.class new file mode 100644 index 0000000..92213bd Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnEntity.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnItemForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnItemForm.class new file mode 100644 index 0000000..bbafa47 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnItemForm.class differ diff --git a/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnUpdateForm.class b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnUpdateForm.class new file mode 100644 index 0000000..bc542d9 Binary files /dev/null and b/yun-base/target/classes/net/lab1024/sa/base/module/support/table/domain/TableColumnUpdateForm.class differ diff --git a/yun-base/target/classes/yun-base.yaml b/yun-base/target/classes/yun-base.yaml new file mode 100644 index 0000000..d267c7c --- /dev/null +++ b/yun-base/target/classes/yun-base.yaml @@ -0,0 +1,186 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useUnicode=true&connectionCollation=utf8mb4_general_ci + username: root + password: root + driver-class-name: com.p6spy.engine.spy.P6SpyDriver + initial-size: 2 + min-idle: 2 + max-active: 10 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: false + method: + pointcut: net.lab1024.sa..*Service.* + + # redis 连接池配置信息 + redis: + database: 1 + host: 127.0.0.1 + port: 6379 + password: + timeout: 10000ms + lettuce: + pool: + max-active: 5 + min-idle: 1 + max-idle: 3 + max-wait: 30000ms + + # 邮件,置以SSL的方式发送, 这个需要使用这种方式并且端口是465 + mail: + host: smtp.163.com + port: 465 + username: lab1024@163.com + password: LAB1024LAB + test-connection: false + properties: + mail: + smtp: + auth: true + ssl: + enable: true + socketFactory: + class: com.sun.mail.util.MailSSLSocketFactory + fallback: false + debug: false + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 上传文件和请求大小 + servlet: + multipart: + max-file-size: 20MB # 单个文件的最大大小 + max-request-size: 10MB # 整个请求的最大大小 + + # 缓存实现类型 + cache: + type: redis + +# 健康检查 +management: + endpoints: + web: + exposure: + include: health,info + health: + mail: + enabled: false + +# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) +server: + tomcat: + basedir: ${project.log-directory}/tomcat-logs + accesslog: + enabled: true + max-days: 7 + pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)" + +# 文件上传 配置 +file: + storage: + mode: local + local: + upload-path: /home/smart_admin_v3/upload/ #文件上传目录 + url-prefix: + cloud: + region: oss-cn-hangzhou + endpoint: oss-cn-hangzhou.aliyuncs.com + bucket-name: 1024lab-smart-admin + access-key: + secret-key: + url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + private-url-expire-seconds: 3600 + +# open api配置 +springdoc: + swagger-ui: + enabled: true # 开关 + doc-expansion: none #关闭展开 + tags-sorter: alpha + server-base-url: + api-docs: + enabled: true # 开关 +knife4j: + enable: true + basic: + enable: false + username: api # Basic认证用户名 + password: 1024 # Basic认证密码 + +# RestTemplate 请求配置 毫秒 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 300 + +# 热加载配置 +reload: + interval-seconds: 300 + +# sa-token 配置 +sa-token: + # token 名称(同时也是 cookie 名称) + token-name: Authorization + # token 前缀 例如:Bearer + token-prefix: Bearer + # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效 + timeout: 2592000 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: false + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false) + is-share: false + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用) + token-style: simple-uuid + # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + auto-renew: true + # 是否输出操作日志 + is-log: true + # 日志等级(trace、debug、info、warn、error、fatal) + log-level: debug + # 启动时的字符画打印 + is-print: false + # 是否从cookie读取token + is-read-cookie: false + +# SmartJob 定时任务配置(不需要可以直接删除以下配置,详细文档请看:https://www.xxxxxx.com) +smart: + job: + enabled: true + # 任务初始化延迟 默认30秒 可选 + init-delay: 10 + # 定时任务执行线程池数量 默认2 可选 + core-pool-size: 2 + # 数据库配置检测-开关 默认开启 可选(作用是固定间隔读取数据库配置更新任务,关闭后只能重启服务或通过接口修改定时任务,建议开启) + db-refresh-enabled: true + # 数据库配置检测-执行间隔 默认120秒 可选 + db-refresh-interval: 60 \ No newline at end of file diff --git a/yun-base/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/yun-base/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..133ef40 --- /dev/null +++ b/yun-base/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,129 @@ +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberInfoBO$SerialNumberInfoBOBuilder.class +net\lab1024\sa\base\common\util\SmartLocalDateUtil.class +net\lab1024\sa\base\module\support\file\domain\vo\FileDownloadVO.class +net\lab1024\sa\base\module\support\job\config\SmartJobConfig.class +net\lab1024\sa\base\module\support\operatelog\domain\OperateLogEntity$OperateLogEntityBuilder.class +net\lab1024\sa\base\module\support\reload\core\domain\SmartReloadObject.class +net\lab1024\sa\base\module\support\serialnumber\service\SerialNumberService.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberRecordEntity$SerialNumberRecordEntityBuilder.class +net\lab1024\sa\base\common\code\ErrorCode.class +net\lab1024\sa\base\module\support\repeatsubmit\RepeatSubmitAspect.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeField.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeTableField.class +net\lab1024\sa\base\module\support\serialnumber\constant\SerialNumberIdEnum.class +net\lab1024\sa\base\module\support\changelog\dao\ChangeLogDao.class +net\lab1024\sa\base\module\support\apiencrypt\service\ApiEncryptServiceSmImpl.class +net\lab1024\sa\base\module\support\datatracer\controller\DataTracerController.class +net\lab1024\sa\base\module\support\repeatsubmit\ticket\RepeatSubmitRedisTicket.class +net\lab1024\sa\base\module\support\loginlog\domain\LoginLogVO.class +net\lab1024\sa\base\module\support\operatelog\core\OperateLogConfig$OperateLogConfigBuilder.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeBasic.class +net\lab1024\sa\base\module\support\repeatsubmit\annoation\RepeatSubmit.class +net\lab1024\sa\base\module\support\securityprotect\domain\LoginFailVO.class +net\lab1024\sa\base\module\support\helpdoc\domain\entity\HelpDocEntity.class +net\lab1024\sa\base\common\enumeration\SystemEnvironmentEnum$SystemEnvironmentNameConst.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberGenerateResultBO$SerialNumberGenerateResultBOBuilder.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeInsertAndUpdate.class +net\lab1024\sa\base\module\support\file\service\IFileStorageService.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberRecordEntity.class +net\lab1024\sa\base\module\support\codegenerator\domain\form\CodeGeneratorConfigForm.class +net\lab1024\sa\base\module\support\heartbeat\core\HeartBeatManager.class +net\lab1024\sa\base\module\support\datatracer\dao\DataTracerDao.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberLastGenerateBO$SerialNumberLastGenerateBOBuilder.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberEntity.class +net\lab1024\sa\base\module\support\table\domain\TableColumnItemForm.class +net\lab1024\sa\base\module\support\datatracer\manager\DataTracerManger.class +net\lab1024\sa\base\module\support\operatelog\domain\OperateLogEntity.class +net\lab1024\sa\base\constant\CacheKeyConst$Dict.class +net\lab1024\sa\base\module\support\heartbeat\core\IHeartBeatRecordHandler.class +net\lab1024\sa\base\module\support\changelog\domain\entity\ChangeLogEntity.class +net\lab1024\sa\base\common\domain\ResponseDTO.class +net\lab1024\sa\base\constant\LoginDeviceEnum.class +net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocDetailVO.class +net\lab1024\sa\base\module\support\file\domain\vo\FileUploadVO.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberLastGenerateBO.class +net\lab1024\sa\base\module\support\feedback\dao\FeedbackDao.class +net\lab1024\sa\base\module\support\reload\core\domain\SmartReloadResult.class +net\lab1024\sa\base\module\support\codegenerator\domain\form\CodeGeneratorConfigForm$CodeGeneratorConfigFormBuilder.class +net\lab1024\sa\base\common\enumeration\BaseEnum$DeletedQuotationAware.class +net\lab1024\sa\base\module\support\reload\domain\ReloadItemVO.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberGenerateResultBO.class +net\lab1024\sa\base\module\support\reload\domain\ReloadItemEntity.class +net\lab1024\sa\base\module\support\feedback\domain\FeedbackAddForm.class +net\lab1024\sa\base\common\controller\SupportBaseController.class +net\lab1024\sa\base\module\support\table\domain\TableColumnUpdateForm.class +net\lab1024\sa\base\module\support\job\api\domain\SmartJobVO.class +net\lab1024\sa\base\module\support\serialnumber\service\impl\SerialNumberMysqlService.class +net\lab1024\sa\base\module\support\job\api\domain\SmartJobLogVO.class +net\lab1024\sa\base\module\support\message\domain\MessageVO.class +net\lab1024\sa\base\module\support\job\core\SmartJob.class +net\lab1024\sa\base\module\support\message\constant\MessageTemplateEnum.class +net\lab1024\sa\base\listener\Ip2RegionListener.class +net\lab1024\sa\base\module\support\reload\core\SmartReloadManager.class +net\lab1024\sa\base\module\support\feedback\domain\FeedbackVO.class +net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocRelationVO.class +net\lab1024\sa\base\common\enumeration\BaseEnum.class +net\lab1024\sa\base\module\support\dict\domain\entity\DictEntity.class +net\lab1024\sa\base\module\support\serialnumber\service\SerialNumberBaseService$1.class +net\lab1024\sa\base\common\enumeration\SystemEnvironmentEnum.class +net\lab1024\sa\base\module\support\config\ConfigDao.class +net\lab1024\sa\base\module\support\mail\constant\MailTemplateTypeEnum.class +net\lab1024\sa\base\module\support\file\domain\entity\FileEntity.class +net\lab1024\sa\base\module\support\reload\core\domain\SmartReloadItem.class +net\lab1024\sa\base\module\support\config\domain\ConfigEntity.class +net\lab1024\sa\base\module\support\message\constant\MessageTypeEnum.class +net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocRelationForm.class +net\lab1024\sa\base\module\support\config\domain\ConfigQueryForm.class +net\lab1024\sa\base\module\support\datatracer\domain\form\DataTracerQueryForm.class +net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\QueryFormVariableService.class +net\lab1024\sa\base\module\support\changelog\domain\form\ChangeLogQueryForm.class +net\lab1024\sa\base\module\support\datatracer\domain\vo\DataTracerVO.class +net\lab1024\sa\base\module\support\serialnumber\service\SerialNumberBaseService.class +net\lab1024\sa\base\module\support\datatracer\service\DataTracerService.class +net\lab1024\sa\base\module\support\apiencrypt\service\ApiEncryptService.class +net\lab1024\sa\base\common\code\UnexpectedErrorCode.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberRecordQueryForm.class +net\lab1024\sa\base\common\domain\PageResult.class +net\lab1024\sa\base\module\support\securityprotect\domain\PasswordLogEntity.class +net\lab1024\sa\base\module\support\serialnumber\constant\SerialNumberRuleTypeEnum.class +net\lab1024\sa\base\module\support\codegenerator\constant\CodeGeneratorConstant.class +net\lab1024\sa\base\module\support\datamasking\DataMaskingTypeEnum.class +net\lab1024\sa\base\module\support\repeatsubmit\ticket\AbstractRepeatSubmitTicket.class +net\lab1024\sa\base\module\support\operatelog\annotation\OperateLog.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeInsertAndUpdateField.class +net\lab1024\sa\base\module\support\feedback\domain\FeedbackEntity.class +net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocAddForm.class +net\lab1024\sa\base\module\support\securityprotect\dao\PasswordLogDao.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeQueryField.class +net\lab1024\sa\base\module\support\reload\core\AbstractSmartReloadCommand.class +net\lab1024\sa\base\module\support\dict\domain\vo\DictVO.class +net\lab1024\sa\base\common\util\SmartDateFormatterEnum.class +net\lab1024\sa\base\module\support\file\domain\vo\FileMetadataVO.class +net\lab1024\sa\base\module\support\heartbeat\core\HeartBeatRecord.class +net\lab1024\sa\base\module\support\dict\domain\entity\DictDataEntity.class +net\lab1024\sa\base\module\support\loginlog\domain\LoginLogEntity.class +net\lab1024\sa\base\module\support\dict\dao\DictDao.class +net\lab1024\sa\base\module\support\datatracer\domain\entity\DataTracerEntity.class +net\lab1024\sa\base\common\domain\PageParam.class +net\lab1024\sa\base\common\domain\SystemEnvironment.class +net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeDelete.class +net\lab1024\sa\base\module\support\job\api\domain\SmartJobExecuteForm.class +net\lab1024\sa\base\config\FileConfig.class +net\lab1024\sa\base\module\support\changelog\domain\vo\ChangeLogVO.class +net\lab1024\sa\base\module\support\operatelog\core\OperateLogConfig.class +net\lab1024\sa\base\common\domain\ValidateData.class +net\lab1024\sa\base\module\support\dict\domain\form\DictQueryForm.class +net\lab1024\sa\base\common\constant\RequestHeaderConst.class +net\lab1024\sa\base\module\support\loginlog\LoginLogResultEnum.class +net\lab1024\sa\base\module\support\codegenerator\service\variable\CodeGenerateBaseVariableService.class +net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocQueryForm.class +net\lab1024\sa\base\module\support\serialnumber\dao\SerialNumberRecordDao.class +net\lab1024\sa\base\module\support\operatelog\domain\OperateLogQueryForm.class +net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberInfoBO.class +net\lab1024\sa\base\module\support\feedback\domain\FeedbackQueryForm.class +net\lab1024\sa\base\module\support\serialnumber\dao\SerialNumberDao.class +net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\QueryFormVariableService$1.class +net\lab1024\sa\base\constant\CacheKeyConst.class +net\lab1024\sa\base\module\support\loginlog\domain\LoginLogEntity$LoginLogEntityBuilder.class +net\lab1024\sa\base\module\support\securityprotect\domain\Level3ProtectConfigForm.class +net\lab1024\sa\base\common\domain\PageParam$SortItem.class diff --git a/yun-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/yun-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..e8af468 --- /dev/null +++ b/yun-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,357 @@ +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\UserPermission.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\enumeration\BaseEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartPageUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\enumeration\DataTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\ResponseDTO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\front\FormVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\service\HelpDocUserService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberRecordEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\constant\ChangeLogTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\core\SmartJobExecutor.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\captcha\CaptchaService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\controller\ChangeLogController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\service\IFileStorageService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\UpdateFormVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\MenuVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobLogVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\core\OperateLogAspect.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\redis\CustomRedisCacheManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\redis\RedisService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\service\SecurityFileService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\vo\DictDataVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\core\SmartJob.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\HeartBeatService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\repository\SmartJobLogDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\cache\RedisCacheServiceImpl.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\front\ConstVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocDetailVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\domain\ReloadForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\service\MessageManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\vo\TableColumnVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\constant\DataTracerTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\service\impl\SerialNumberMysqlService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\dao\CodeGeneratorConfigDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\domain\HeartBeatRecordVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeInsertAndUpdateField.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\form\FileUrlUploadForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\listener\Ip2RegionListener.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\constant\MessageTemplateEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\domain\LoginFailEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\deserializer\DictDataDeserializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\domain\form\DataTracerQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\SmartJobService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\redis\RedissonService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\service\FileService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\SmartReloadManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\constant\StringConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobExecuteForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\service\impl\SerialNumberInternService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\repeatsubmit\annoation\RepeatSubmit.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\util\CodeGeneratorTool.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\controller\FeedbackController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\domain\FeedbackAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\deserializer\FileKeyVoDeserializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\domain\form\ChangeLogQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\form\FileQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\enumeration\EnumSerializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\domain\MessageQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\annoation\DataTracerFieldEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\DataSourceConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\loginlog\LoginLogService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\swagger\SchemaEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\annoation\DataTracerFieldSql.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datamasking\SmartDataMaskingUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\service\ApiEncryptServiceSmImpl.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\constant\SmartJobConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\service\MessageService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\ConfigDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\constant\CodeFrontComponentEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\ValidateList.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\dao\MessageDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeDelete.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\controller\SupportBaseController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\entity\DictDataEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocCatalogAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\service\HelpDocService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\form\TableQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartRequestUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartExcelUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\repository\SmartJobRepository.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\redis\RedissonPasswordConfigurationCustomizer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\VOVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\FileKeySerializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\domain\FeedbackVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\LongJsonSerializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocRelationVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\RedisConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartVerificationUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\core\SmartJobScheduler.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobMsg.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\annotation\ApiDecrypt.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\code\SystemErrorCode.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\repository\domain\SmartJobLogEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\CorsFilterConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\dao\DataTracerDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\constant\FileFolderTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\AbstractSmartReloadCommand.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\vo\TableConfigVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\entity\HelpDocCatalogEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\manager\DataTracerManger.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberInfoBO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\domain\bo\DataTracerContentBO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberLastGenerateBO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\form\CodeGeneratorPreviewForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\captcha\domain\CaptchaVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\loginlog\domain\LoginLogVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\repository\SmartJobDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartResponseUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\AddFormVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\dao\DictDataDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\dao\ChangeLogDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocCatalogVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\service\impl\SerialNumberRedisService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\service\HelpDocCatalogService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\domain\OperateLogQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\enumeration\SystemEnvironmentEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\dao\PasswordLogDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\loginlog\domain\LoginLogQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\SmartJobClientManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\constant\MessageTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\annotation\ApiEncrypt.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\code\UserErrorCode.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\ControllerVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\domain\HeartBeatRecordQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\mail\MailTemplateDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\service\DataTracerService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\constant\SmartJobUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartEnumUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\ReloadCommand.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\core\IHeartBeatRecordHandler.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\domain\MessageTemplateSendForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\annoation\DataTracerFieldLabel.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\form\DictUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\entity\HelpDocEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\captcha\domain\CaptchaForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\constant\CodeQueryFieldQueryTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberGenerateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\domain\ConfigAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\service\SerialNumberService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartIpUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\captcha\CaptchaController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\front\ApiVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\ConfigController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\RestTemplateConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\loginlog\domain\LoginLogEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\service\Level3ProtectConfigService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\code\UnexpectedErrorCode.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\table\domain\TableColumnUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\table\domain\TableColumnItemForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\service\FileStorageLocalServiceImpl.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\constant\SmartJobTriggerTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\domain\form\DataTracerForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeInsertAndUpdate.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\dao\HelpDocCatalogDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeQueryField.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\dao\FeedbackDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeField.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\OperateLogDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\EntityVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\FileKeyVoSerializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\swagger\SchemaEnumPropertyCustomizer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobEnabledUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\table\TableColumnDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\constant\CodeGeneratorConstant.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\validator\enumeration\EnumValidator.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\domain\ConfigQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\domain\FeedbackEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\mail\constant\MailTemplateTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\service\ApiEncryptService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\domain\form\ChangeLogAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\code\ErrorCodeRegister.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\config\SmartJobConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\code\ErrorCodeRangeContainer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\domain\ApiEncryptForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocViewRecordQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\ConfigService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\form\DictQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\CacheConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\RepeatSubmitConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\HeartBeatRecordHandler.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\DataMaskingSerializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\entity\DictEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\form\CodeGeneratorConfigForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeBasic.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\sample\SmartJobSample2.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\front\ListVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\constant\DataTracerConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\repeatsubmit\ticket\RepeatSubmitMemoryTicket.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\entity\FileEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\OperateLogService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\vo\FileVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\exception\BusinessException.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\service\FeedbackService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\domain\Level3ProtectConfigForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\CodeGeneratorService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\SwaggerConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\constant\SerialNumberRuleTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\form\DictDataUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\RequestUrlVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\domain\entity\DataTracerEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\domain\SmartReloadItem.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\table\domain\TableColumnEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\FileConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\enumeration\UserTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\ServiceVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\MapperVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\listener\LogVariableListener.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\service\ChangeLogService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartBigDecimalUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\controller\CodeGeneratorController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\annoation\DataTracerFieldDict.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\code\ErrorCode.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\HeartBeatRecordDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\repeatsubmit\RepeatSubmitAspect.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\mail\MailService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\dao\DictDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\constant\RequestHeaderConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\enumeration\GenderEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\handler\GlobalExceptionHandler.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartLocalDateUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberRecordQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\vo\FileDownloadVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\annotation\OperateLog.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\dao\ReloadItemDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\dao\FileDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\dao\HelpDocDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\advice\DecryptRequestAdvice.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\enumeration\EnumSerialize.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\form\DictDataAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\vo\DictVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\domain\SmartReloadResult.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datamasking\DataMaskingTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\service\FileStorageCloudServiceImpl.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\sample\SmartJobSample1.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\constant\SwaggerTagConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\serializer\BigDecimalNullZeroSerializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\core\HeartBeatRecord.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\domain\form\ChangeLogUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\annoation\DataTracerFieldBigDecimal.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\listener\WebServerListener.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\core\HeartBeatManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\manager\HelpDocManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\dao\LoginFailDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\domain\entity\ChangeLogEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\CodeGeneratorTemplateService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\service\DataTracerChangeContentService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\entity\CodeGeneratorConfigEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\core\OperateLogConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\service\SecurityPasswordService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\RequestUser.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\domain\ReloadItemEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\TokenConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocCatalogUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\service\SecurityLoginService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\SystemEnvironment.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\cache\CaffeineCacheServiceImpl.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\PageParam.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\service\SerialNumberBaseService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocRelationForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\ReloadService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\annoation\NoNeedLogin.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\table\TableColumnService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\controller\FileController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\domain\ConfigEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\domain\OperateLogEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\controller\MessageController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\YamlProcessor.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\dao\CodeGeneratorDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\DataScopePlugin.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\constant\CacheKeyConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\domain\form\DictAddForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\controller\HelpDocController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\domain\ReloadItemVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\domain\ReloadResultEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\domain\ReloadResultVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\vo\FileMetadataVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datamasking\DataMasking.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\mail\domain\MailTemplateEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\dao\SerialNumberDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartStringUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\DaoVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\domain\SmartReloadObject.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\constant\CodeDeleteEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\api\domain\SmartJobLogQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\domain\MessageVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\domain\MessageEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\HeartBeatConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocViewRecordVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\dao\SerialNumberRecordDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\json\deserializer\LongJsonDeserializer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\thread\SmartReloadRunnable.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\ConfigKeyEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\core\SmartJobLauncher.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\config\SmartJobAutoConfiguration.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\mail\constant\MailTemplateCodeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\PageResult.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartDateFormatterEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\vo\TableVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\domain\model\CodeTableField.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\domain\ConfigUpdateForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\advice\EncryptResponseAdvice.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\domain\LoginFailQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\constant\ReloadConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\loginlog\LoginLogDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\changelog\domain\vo\ChangeLogVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\domain\PasswordLogEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\ScheduleConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\vo\HelpDocRecordVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\manager\DictManager.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\file\domain\vo\FileUploadVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\constant\LoginDeviceEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\handler\MybatisPlusFillHandler.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\sample\package-info.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\core\annoation\SmartReload.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\loginlog\LoginLogResultEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\ManagerVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\domain\ValidateData.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\util\SmartBeanUtil.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\core\HeartBeatRunnable.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\domain\SerialNumberGenerateResultBO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\feedback\domain\FeedbackQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\AsyncConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\swagger\SmartOperationCustomizer.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\SystemEnvironmentConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\constant\CodeGeneratorPageTypeEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\MybatisPlusConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\constant\RedisKeyConst.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\JsonConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\operatelog\domain\OperateLogVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\repeatsubmit\ticket\AbstractRepeatSubmitTicket.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\config\UrlConfig.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\heartbeat\domain\HeartBeatRecordEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\table\TableColumnController.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\reload\dao\ReloadResultDao.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\job\repository\domain\SmartJobEntity.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\repeatsubmit\ticket\RepeatSubmitRedisTicket.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\securityprotect\domain\LoginFailVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\config\domain\ConfigVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\message\domain\MessageSendForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\apiencrypt\service\ApiEncryptServiceAesImpl.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\CodeGenerateBaseVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\constant\SerialNumberIdEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\codegenerator\service\variable\backend\domain\QueryFormVariableService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\common\validator\enumeration\CheckEnum.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\helpdoc\domain\form\HelpDocQueryForm.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\cache\CacheService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\serialnumber\service\SerialNumberRecordService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\domain\vo\DataTracerVO.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\dict\service\DictService.java +E:\sanduo\ls\yun-parent\yun-base\src\main\java\net\lab1024\sa\base\module\support\datatracer\controller\DataTracerController.java