diff --git a/db-file/opsli-boot.sql b/db-file/opsli-boot.sql index 5cf52c7344f1e3293d3ee40f790bb0b01d8c6a79..c84298a326e66f6b88a202ba699dadd5ee07252b 100644 --- a/db-file/opsli-boot.sql +++ b/db-file/opsli-boot.sql @@ -213,7 +213,7 @@ INSERT INTO `gen_template_detail` VALUES (1448185089241038850, 13982537047248281 INSERT INTO `gen_template_detail` VALUES (1448185089689829378, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/mapper/xml', '${model.tableHumpName}Mapper.xml', '\n\n#if(data.subModuleName != null && data.subModuleName != \"\")\n\n#else\n\n#end\n\n\n', '0', 0, 1313694379541635074, '2021-10-13 15:13:26', 1313694379541635074, '2021-10-13 15:13:26'); INSERT INTO `gen_template_detail` VALUES (1448185090205728769, 1398253704724828162, '0', 'org/opsli/api/wrapper/${moduleName}/${subModuleName}', '${model.tableHumpName}Model.java', '#if(data.subModuleName != null && data.subModuleName != \"\")\npackage #(apiPath).wrapper.#(data.moduleName+\".\"+data.subModuleName);\n#else\npackage #(apiPath).wrapper.#(data.moduleName);\n#end\n\n#for(pkg : data.model.entityPkgList)\nimport #(pkg);\n#end\nimport com.alibaba.excel.annotation.ExcelProperty;\nimport io.swagger.annotations.ApiModelProperty;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport #(apiPath).base.warpper.ApiWrapper;\nimport org.opsli.common.annotation.validator.Validator;\nimport org.opsli.common.annotation.validator.ValidatorLenMax;\nimport org.opsli.common.annotation.validator.ValidatorLenMin;\nimport org.opsli.common.enums.ValidatorType;\nimport org.opsli.plugins.excel.annotation.ExcelInfo;\nimport com.fasterxml.jackson.annotation.JsonFormat;\nimport org.springframework.format.annotation.DateTimeFormat;\n\n/**\n* #(data.codeTitle) Model\n*\n* @author #(data.authorName)\n* @date #(currTime)\n*/\n@Data\n@EqualsAndHashCode(callSuper = false)\npublic class #(data.model.tableHumpName)Model extends ApiWrapper {\n\n #for(column : data.model.columnList)\n ### 不等于 删除字段 和 不等于 租户字段放入上边\n #if(column.fieldHumpName != \"deleted\" && column.fieldHumpName != \"tenantId\")\n /** #(column.fieldComments) */\n @ApiModelProperty(value = \"#(column.fieldComments)\")\n @ExcelProperty(value = \"#(column.fieldComments)\", order = #(column.sort))\n #if(column.dictTypeCode != null && column.dictTypeCode != \"\")\n @ExcelInfo( dictType = \"#(column.dictTypeCode)\" )\n #else\n @ExcelInfo\n #end\n #if(column.validateTypeAndCommaList != null && column.validateTypeAndCommaList.size() > 0)\n @Validator({\n #for(typeAndComma : column.validateTypeAndCommaList)\n ValidatorType.#(typeAndComma)\n #end\n })\n #end\n #if(column.fieldLength != null && column.fieldLength > 0)\n #if(column.fieldPrecision != null && column.fieldPrecision > 0)\n @ValidatorLenMax(#(column.fieldLength+column.fieldPrecision))\n #else\n @ValidatorLenMax(#(column.fieldLength))\n #end\n #end\n ### 日期处理\n #if(column.javaType == \"Date\")\n #if(column.showType == \"4\")\n @JsonFormat(timezone = \"GMT+8\", pattern = \"yyyy-MM-dd\")\n @DateTimeFormat(pattern = \"yyyy-MM-dd\")\n #else\n @JsonFormat(timezone = \"GMT+8\", pattern = \"yyyy-MM-dd HH:mm:ss\")\n @DateTimeFormat(pattern = \"yyyy-MM-dd HH:mm:ss\")\n #end\n #end\n private #(column.javaType) #(column.fieldHumpName);\n\n #end\n #end\n\n\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:26', 1313694379541635074, '2021-10-13 15:13:26'); INSERT INTO `gen_template_detail` VALUES (1448185092231577601, 1398253704724828162, '0', 'org/opsli/api/web/${moduleName}/${subModuleName}', '${model.tableHumpName}RestApi.java', '#if(data.subModuleName != null && data.subModuleName != \"\")\npackage #(apiPath).web.#(data.moduleName+\".\"+data.subModuleName);\n#else\npackage #(apiPath).web.#(data.moduleName);\n#end\n\nimport #(apiPath).base.result.ResultVo;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\n#if(data.subModuleName != null && data.subModuleName != \"\")\nimport #(apiPath).wrapper.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)Model;\n#else\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\n#end\n\n\n/**\n * #(data.codeTitle) Api\n *\n * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping\n * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起\n *\n * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的\n *\n * @author #(data.authorName)\n * @date #(currTime)\n */\npublic interface #(data.model.tableHumpName)RestApi {\n\n /** 标题 */\n String TITLE = \"#(data.codeTitle)\";\n /** 子标题 */\n String SUB_TITLE = \"#(data.codeTitleBrief)\";\n\n /**\n * #(data.codeTitle) 查一条\n * @param model 模型\n * @return ResultVo\n */\n @GetMapping(\"/get\")\n ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 查询分页\n * @param pageNo 当前页\n * @param pageSize 每页条数\n * @param request request\n * @return ResultVo\n */\n @GetMapping(\"/findPage\")\n ResultVo findPage(\n @RequestParam(name = \"pageNo\", defaultValue = \"1\") Integer pageNo,\n @RequestParam(name = \"pageSize\", defaultValue = \"10\") Integer pageSize,\n HttpServletRequest request\n );\n\n /**\n * #(data.codeTitle) 新增\n * @param model 模型\n * @return ResultVo\n */\n @PostMapping(\"/insert\")\n ResultVo insert(@RequestBody #(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 修改\n * @param model 模型\n * @return ResultVo\n */\n @PostMapping(\"/update\")\n ResultVo update(@RequestBody #(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 删除\n * @param id ID\n * @return ResultVo\n */\n @PostMapping(\"/del\")\n ResultVo del(String id);\n\n /**\n * #(data.codeTitle) 批量删除\n * @param ids ID 数组\n * @return ResultVo\n */\n @PostMapping(\"/delAll\")\n ResultVo delAll(String ids);\n\n /**\n * #(data.codeTitle) Excel 导出\n *\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\n * 因为在 导出不成功时,需要推送错误信息,\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\n * response 推送 javascript代码 alert 提示报错信息\n *\n * @param request request\n * @param response response\n */\n @GetMapping(\"/exportExcel\")\n void exportExcel(HttpServletRequest request, HttpServletResponse response);\n\n /**\n * #(data.codeTitle) Excel 导入\n * @param request 文件流 request\n * @return ResultVo\n */\n @PostMapping(\"/importExcel\")\n ResultVo importExcel(MultipartHttpServletRequest request);\n\n /**\n * #(data.codeTitle) Excel 下载导入模版\n * @param response response\n */\n @GetMapping(\"/importExcel/template\")\n void importTemplate(HttpServletResponse response);\n\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:27', 1313694379541635074, '2021-10-13 15:13:27'); -INSERT INTO `gen_template_detail` VALUES (1448185095272448002, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/web', '${model.tableHumpName}RestController.java', '#if(data.subModuleName != null && data.subModuleName != \"\")\npackage #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).web;\n#else\npackage #(data.packageName+\".\"+data.moduleName).web;\n#end\n\nimport cn.hutool.core.util.ReflectUtil;\nimport cn.hutool.core.convert.Convert;\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiOperation;\nimport lombok.extern.slf4j.Slf4j;\nimport org.opsli.common.annotation.RequiresPermissionsCus;\nimport org.apache.shiro.authz.annotation.RequiresPermissions;\nimport #(apiPath).base.result.ResultVo;\nimport org.opsli.common.annotation.ApiRestController;\nimport org.opsli.common.annotation.EnableLog;\nimport org.opsli.core.base.controller.BaseRestController;\nimport org.opsli.core.persistence.Page;\nimport org.opsli.core.persistence.querybuilder.QueryBuilder;\nimport org.opsli.core.persistence.querybuilder.WebQueryBuilder;\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.lang.reflect.Method;\n\n#if(data.subModuleName != null && data.subModuleName != \"\")\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)Model;\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\nimport #(apiPath).web.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)RestApi;\n#else\nimport #(data.packageName+\".\"+data.moduleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\nimport #(data.packageName+\".\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\nimport #(apiPath).web.#(data.moduleName).#(data.model.tableHumpName)RestApi;\n#end\n\n/**\n * #(data.codeTitle) Controller\n *\n * @author #(data.authorName)\n * @date #(currTime)\n */\n@Api(tags = #(data.model.tableHumpName)RestApi.TITLE)\n@Slf4j\n#if(data.subModuleName != null && data.subModuleName != \"\")\n@ApiRestController(\"/#(data.moduleName)/#(data.subModuleName)\")\n#else\n@ApiRestController(\"/#(data.moduleName)\")\n#end\npublic class #(data.model.tableHumpName)RestController extends BaseRestController<#(data.model.tableHumpName), #(data.model.tableHumpName)Model, I#(data.model.tableHumpName)Service>\n implements #(data.model.tableHumpName)RestApi {\n\n\n /**\n * #(data.codeTitleBrief) 查一条\n * @param model 模型\n * @return ResultVo\n */\n @ApiOperation(value = \"获得单条#(data.codeTitleBrief)\", notes = \"获得单条#(data.codeTitleBrief) - ID\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_select\")\n #end\n @Override\n public ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model) {\n // 如果系统内部调用 则直接查数据库\n if(model != null && model.getIzApi() != null && model.getIzApi()){\n model = IService.get(model);\n }\n return ResultVo.success(model);\n }\n\n /**\n * #(data.codeTitleBrief) 查询分页\n * @param pageNo 当前页\n * @param pageSize 每页条数\n * @param request request\n * @return ResultVo\n */\n @ApiOperation(value = \"获得分页数据\", notes = \"获得分页数据 - 查询构造器\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_select\")\n #end\n @Override\n public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {\n\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\n Page<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> page = new Page<>(pageNo, pageSize);\n page.setQueryWrapper(queryBuilder.build());\n page = IService.findPage(page);\n\n return ResultVo.success(page.getPageData());\n }\n\n /**\n * #(data.codeTitleBrief) 新增\n * @param model 模型\n * @return ResultVo\n */\n @ApiOperation(value = \"新增#(data.codeTitleBrief)数据\", notes = \"新增#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_insert\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_insert\")\n #end\n @EnableLog\n @Override\n public ResultVo insert(#(data.model.tableHumpName)Model model) {\n // 调用新增方法\n IService.insert(model);\n return ResultVo.success(\"新增#(data.codeTitleBrief)成功\");\n }\n\n /**\n * #(data.codeTitleBrief) 修改\n * @param model 模型\n * @return ResultVo\n */\n @ApiOperation(value = \"修改#(data.codeTitleBrief)数据\", notes = \"修改#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_update\")\n #end\n @EnableLog\n @Override\n public ResultVo update(#(data.model.tableHumpName)Model model) {\n // 调用修改方法\n IService.update(model);\n return ResultVo.success(\"修改#(data.codeTitleBrief)成功\");\n }\n\n\n /**\n * #(data.codeTitleBrief) 删除\n * @param id ID\n * @return ResultVo\n */\n @ApiOperation(value = \"删除#(data.codeTitleBrief)数据\", notes = \"删除#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_update\")\n #end\n @EnableLog\n @Override\n public ResultVo del(String id){\n IService.delete(id);\n return ResultVo.success(\"删除#(data.codeTitleBrief)成功\");\n }\n\n /**\n * #(data.codeTitleBrief) 批量删除\n * @param ids ID 数组\n * @return ResultVo\n */\n @ApiOperation(value = \"批量删除#(data.codeTitleBrief)数据\", notes = \"批量删除#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_update\")\n #end\n @EnableLog\n @Override\n public ResultVo delAll(String ids){\n String[] idArray = Convert.toStrArray(ids);\n IService.deleteAll(idArray);\n return ResultVo.success(\"批量删除#(data.codeTitleBrief)成功\");\n }\n\n\n /**\n * #(data.codeTitleBrief) Excel 导出\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\n *\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\n * 因为在 导出不成功时,需要推送错误信息,\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\n * response 推送 javascript代码 alert 提示报错信息\n *\n * @param request request\n * @param response response\n */\n @ApiOperation(value = \"导出Excel\", notes = \"导出Excel\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_export\")\n #else\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_export\")\n #end\n @EnableLog\n @Override\n public void exportExcel(HttpServletRequest request, HttpServletResponse response) {\n // 当前方法\n Method method = ReflectUtil.getMethodByName(this.getClass(), \"exportExcel\");\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\n super.excelExport(#(data.model.tableHumpName)RestApi.SUB_TITLE, queryBuilder.build(), response, method);\n }\n\n /**\n * #(data.codeTitleBrief) Excel 导入\n * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解\n * @param request 文件流 request\n * @return ResultVo\n */\n @ApiOperation(value = \"导入Excel\", notes = \"导入Excel\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_import\")\n #end\n @EnableLog\n @Override\n public ResultVo importExcel(MultipartHttpServletRequest request) {\n return super.importExcel(request);\n }\n\n /**\n * #(data.codeTitleBrief) Excel 下载导入模版\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\n * @param response response\n */\n @ApiOperation(value = \"导出Excel模版\", notes = \"导出Excel模版\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\")\n #else\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_import\")\n #end\n @Override\n public void importTemplate(HttpServletResponse response) {\n // 当前方法\n Method method = ReflectUtil.getMethodByName(this.getClass(), \"importTemplate\");\n super.importTemplate(#(data.model.tableHumpName)RestApi.SUB_TITLE, response, method);\n }\n\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:27', 1313694379541635074, '2021-10-13 15:13:27'); +INSERT INTO `gen_template_detail` VALUES (1448185095272448002, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/web', '${model.tableHumpName}RestController.java', '#if(data.subModuleName != null && data.subModuleName != \"\")\npackage #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).web;\n#else\npackage #(data.packageName+\".\"+data.moduleName).web;\n#end\n\nimport cn.hutool.core.util.ReflectUtil;\nimport cn.hutool.core.convert.Convert;\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiOperation;\nimport lombok.extern.slf4j.Slf4j;\nimport org.opsli.common.annotation.RequiresPermissionsCus;\nimport org.apache.shiro.authz.annotation.RequiresPermissions;\nimport #(apiPath).base.result.ResultVo;\nimport org.opsli.common.annotation.ApiRestController;\nimport org.opsli.common.annotation.EnableLog;\nimport org.opsli.core.base.controller.BaseRestController;\nimport org.opsli.core.persistence.Page;\nimport org.opsli.core.persistence.querybuilder.QueryBuilder;\nimport org.opsli.core.persistence.querybuilder.WebQueryBuilder;\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.lang.reflect.Method;\n\n#if(data.subModuleName != null && data.subModuleName != \"\")\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)Model;\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\nimport #(apiPath).web.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)RestApi;\n#else\nimport #(data.packageName+\".\"+data.moduleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\nimport #(data.packageName+\".\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\nimport #(apiPath).web.#(data.moduleName).#(data.model.tableHumpName)RestApi;\n#end\n\n/**\n * #(data.codeTitle) Controller\n *\n * @author #(data.authorName)\n * @date #(currTime)\n */\n@Api(tags = #(data.model.tableHumpName)RestApi.TITLE)\n@Slf4j\n#if(data.subModuleName != null && data.subModuleName != \"\")\n@ApiRestController(\"/{ver}/#(data.moduleName)/#(data.subModuleName)\")\n#else\n@ApiRestController(\"/{ver}/#(data.moduleName)\")\n#end\npublic class #(data.model.tableHumpName)RestController extends BaseRestController<#(data.model.tableHumpName), #(data.model.tableHumpName)Model, I#(data.model.tableHumpName)Service>\n implements #(data.model.tableHumpName)RestApi {\n\n\n /**\n * #(data.codeTitleBrief) 查一条\n * @param model 模型\n * @return ResultVo\n */\n @ApiOperation(value = \"获得单条#(data.codeTitleBrief)\", notes = \"获得单条#(data.codeTitleBrief) - ID\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_select\")\n #end\n @Override\n public ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model) {\n // 如果系统内部调用 则直接查数据库\n if(model != null && model.getIzApi() != null && model.getIzApi()){\n model = IService.get(model);\n }\n return ResultVo.success(model);\n }\n\n /**\n * #(data.codeTitleBrief) 查询分页\n * @param pageNo 当前页\n * @param pageSize 每页条数\n * @param request request\n * @return ResultVo\n */\n @ApiOperation(value = \"获得分页数据\", notes = \"获得分页数据 - 查询构造器\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_select\")\n #end\n @Override\n public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {\n\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\n Page<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> page = new Page<>(pageNo, pageSize);\n page.setQueryWrapper(queryBuilder.build());\n page = IService.findPage(page);\n\n return ResultVo.success(page.getPageData());\n }\n\n /**\n * #(data.codeTitleBrief) 新增\n * @param model 模型\n * @return ResultVo\n */\n @ApiOperation(value = \"新增#(data.codeTitleBrief)数据\", notes = \"新增#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_insert\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_insert\")\n #end\n @EnableLog\n @Override\n public ResultVo insert(#(data.model.tableHumpName)Model model) {\n // 调用新增方法\n IService.insert(model);\n return ResultVo.success(\"新增#(data.codeTitleBrief)成功\");\n }\n\n /**\n * #(data.codeTitleBrief) 修改\n * @param model 模型\n * @return ResultVo\n */\n @ApiOperation(value = \"修改#(data.codeTitleBrief)数据\", notes = \"修改#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_update\")\n #end\n @EnableLog\n @Override\n public ResultVo update(#(data.model.tableHumpName)Model model) {\n // 调用修改方法\n IService.update(model);\n return ResultVo.success(\"修改#(data.codeTitleBrief)成功\");\n }\n\n\n /**\n * #(data.codeTitleBrief) 删除\n * @param id ID\n * @return ResultVo\n */\n @ApiOperation(value = \"删除#(data.codeTitleBrief)数据\", notes = \"删除#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_update\")\n #end\n @EnableLog\n @Override\n public ResultVo del(String id){\n IService.delete(id);\n return ResultVo.success(\"删除#(data.codeTitleBrief)成功\");\n }\n\n /**\n * #(data.codeTitleBrief) 批量删除\n * @param ids ID 数组\n * @return ResultVo\n */\n @ApiOperation(value = \"批量删除#(data.codeTitleBrief)数据\", notes = \"批量删除#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_update\")\n #end\n @EnableLog\n @Override\n public ResultVo delAll(String ids){\n String[] idArray = Convert.toStrArray(ids);\n IService.deleteAll(idArray);\n return ResultVo.success(\"批量删除#(data.codeTitleBrief)成功\");\n }\n\n\n /**\n * #(data.codeTitleBrief) Excel 导出\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\n *\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\n * 因为在 导出不成功时,需要推送错误信息,\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\n * response 推送 javascript代码 alert 提示报错信息\n *\n * @param request request\n * @param response response\n */\n @ApiOperation(value = \"导出Excel\", notes = \"导出Excel\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_export\")\n #else\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_export\")\n #end\n @EnableLog\n @Override\n public void exportExcel(HttpServletRequest request, HttpServletResponse response) {\n // 当前方法\n Method method = ReflectUtil.getMethodByName(this.getClass(), \"exportExcel\");\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\n super.excelExport(#(data.model.tableHumpName)RestApi.SUB_TITLE, queryBuilder.build(), response, method);\n }\n\n /**\n * #(data.codeTitleBrief) Excel 导入\n * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解\n * @param request 文件流 request\n * @return ResultVo\n */\n @ApiOperation(value = \"导入Excel\", notes = \"导入Excel\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\")\n #else\n @RequiresPermissions(\"#(data.moduleName.toLowerCase())_import\")\n #end\n @EnableLog\n @Override\n public ResultVo importExcel(MultipartHttpServletRequest request) {\n return super.importExcel(request);\n }\n\n /**\n * #(data.codeTitleBrief) Excel 下载导入模版\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\n * @param response response\n */\n @ApiOperation(value = \"导出Excel模版\", notes = \"导出Excel模版\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\")\n #else\n @RequiresPermissionsCus(\"#(data.moduleName.toLowerCase())_import\")\n #end\n @Override\n public void importTemplate(HttpServletResponse response) {\n // 当前方法\n Method method = ReflectUtil.getMethodByName(this.getClass(), \"importTemplate\");\n super.importTemplate(#(data.model.tableHumpName)RestApi.SUB_TITLE, response, method);\n }\n\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:27', 1313694379541635074, '2021-10-13 15:13:27'); INSERT INTO `gen_template_detail` VALUES (1448185098657251330, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/service/impl', '${model.tableHumpName}ServiceImpl.java', '#if(data.subModuleName != null && data.subModuleName != \"\")\npackage #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).service.impl;\n#else\npackage #(data.packageName+\".\"+data.moduleName).service.impl;\n#end\n\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\nimport org.opsli.core.base.service.impl.CrudServiceImpl;\n\n#if(data.subModuleName != null && data.subModuleName != \"\")\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)Model;\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).mapper.#(data.model.tableHumpName)Mapper;\n#else\nimport #(data.packageName+\".\"+data.moduleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\nimport #(data.packageName+\".\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\nimport #(data.packageName+\".\"+data.moduleName).mapper.#(data.model.tableHumpName)Mapper;\n#end\n\n\n/**\n * #(data.codeTitle) Service Impl\n *\n * @author #(data.authorName)\n * @date #(currTime)\n */\n@Service\npublic class #(data.model.tableHumpName)ServiceImpl extends CrudServiceImpl<#(data.model.tableHumpName)Mapper, #(data.model.tableHumpName), #(data.model.tableHumpName)Model>\n implements I#(data.model.tableHumpName)Service {\n\n @Autowired(required = false)\n private #(data.model.tableHumpName)Mapper mapper;\n\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:28', 1313694379541635074, '2021-10-13 15:13:28'); INSERT INTO `gen_template_detail` VALUES (1448185102641840129, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/service', 'I${model.tableHumpName}Service.java', '#if(data.subModuleName != null && data.subModuleName != \"\")\npackage #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).service;\n#else\npackage #(data.packageName+\".\"+data.moduleName).service;\n#end\n\nimport org.opsli.core.base.service.interfaces.CrudServiceInterface;\n\n\n#if(data.subModuleName != null && data.subModuleName != \"\")\nimport #(data.packageName+\".\"+data.moduleName+\".\"+data.subModuleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName+\".\"+data.subModuleName).#(data.model.tableHumpName)Model;\n#else\nimport #(data.packageName+\".\"+data.moduleName).entity.#(data.model.tableHumpName);\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\n#end\n\n/**\n * #(data.codeTitle) Service\n *\n * @author #(data.authorName)\n * @date #(currTime)\n */\npublic interface I#(data.model.tableHumpName)Service extends CrudServiceInterface<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> {\n\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:29', 1313694379541635074, '2021-10-13 15:13:29'); INSERT INTO `gen_template_detail` VALUES (1448185107255574530, 1398253704724828162, '1', 'src/api/${moduleName}/${subModuleName}', '${model.tableHumpName}ManagementApi.js', 'import request from \"@/utils/request\";\nimport { downloadFileByData } from \"@/utils/download\";\n\nexport function getList(data) {\n return request({\n #if(data.subModuleName != null && data.subModuleName != \"\")\n url: \"/api/v1/#(data.moduleName)/#(data.subModuleName)/findPage\",\n #else\n url: \"/api/v1/#(data.moduleName)/findPage\",\n #end\n method: \"get\",\n params: data,\n });\n}\n\nexport function doInsert(data) {\n return request({\n #if(data.subModuleName != null && data.subModuleName != \"\")\n url: \"/api/v1/#(data.moduleName)/#(data.subModuleName)/insert\",\n #else\n url: \"/api/v1/#(data.moduleName)/insert\",\n #end\n method: \"post\",\n data,\n });\n}\n\nexport function doUpdate(data) {\n return request({\n #if(data.subModuleName != null && data.subModuleName != \"\")\n url: \"/api/v1/#(data.moduleName)/#(data.subModuleName)/update\",\n #else\n url: \"/api/v1/#(data.moduleName)/update\",\n #end\n method: \"post\",\n data,\n });\n}\n\nexport function doDelete(data) {\n return request({\n #if(data.subModuleName != null && data.subModuleName != \"\")\n url: \"/api/v1/#(data.moduleName)/#(data.subModuleName)/del\",\n #else\n url: \"/api/v1/#(data.moduleName)/del\",\n #end\n method: \"post\",\n params: data,\n });\n}\n\nexport function doDeleteAll(data) {\n return request({\n #if(data.subModuleName != null && data.subModuleName != \"\")\n url: \"/api/v1/#(data.moduleName)/#(data.subModuleName)/delAll\",\n #else\n url: \"/api/v1/#(data.moduleName)/delAll\",\n #end\n method: \"post\",\n params: data,\n });\n}\n\n/**\n * 导出Excel 目前只支持一层参数传递\n * @param data\n * @returns file\n */\nexport function doExportExcel(data) {\n #if(data.subModuleName != null && data.subModuleName != \"\")\n let requestURL = \"/api/v1/#(data.moduleName)/#(data.subModuleName)/exportExcel\";\n #else\n let requestURL = \"/api/v1/#(data.moduleName)/exportExcel\";\n #end\n // 下载文件\n downloadFileByData(requestURL, data);\n}\n\n/**\n * 下载模版\n * @returns file\n */\nexport function doDownloadTemplate() {\n let data = {};\n #if(data.subModuleName != null && data.subModuleName != \"\")\n let requestURL = \"/api/v1/#(data.moduleName)/#(data.subModuleName)/importExcel/template\";\n #else\n let requestURL = \"/api/v1/#(data.moduleName)/importExcel/template\";\n #end\n // 下载文件\n downloadFileByData(requestURL, data);\n}\n\n/**\n * 导入Excel\n * @returns file\n */\nexport function doImportExcel(data) {\n return request({\n #if(data.subModuleName != null && data.subModuleName != \"\")\n url: \"/api/v1/#(data.moduleName)/#(data.subModuleName)/importExcel\",\n #else\n url: \"/api/v1/#(data.moduleName)/importExcel\",\n #end\n method: \"post\",\n // 最长超时时间 3 分钟\n timeout: 180000,\n headers: {\n \"Content-Type\": \"multipart/form-data\"\n },\n data,\n });\n}', '0', 0, 1313694379541635074, '2021-10-13 15:13:30', 1313694379541635074, '2021-10-13 15:13:30'); @@ -3865,8 +3865,6 @@ INSERT INTO `sys_logs` VALUES (1465622869848043521, '1', '组织机构-组织管 INSERT INTO `sys_logs` VALUES (1465622894762209281, '1', '测试模块-业务测试-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/test/v1/update', 'POST', 250, '[{\"izApi\":false,\"type\":\"0\",\"version\":1,\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1638178842000,\"name\":\"222\",\"id\":\"1465254379886661634\"}]', NULL, 0, 1313694379541635074, '2021-11-30 18:05:03', 1313694379541635074, '2021-11-30 18:05:03', '2021-11-30 18:02:48'); INSERT INTO `sys_logs` VALUES (1465622911006748673, '1', '测试模块-某系统用户-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/gentest/user/v1/update', 'POST', 231, '[{\"izUsable\":\"0\",\"birth\":312825600000,\"izApi\":false,\"version\":9,\"createBy\":\"1313694379541635074\",\"money\":9999,\"izManual\":false,\"createTime\":1607907107000,\"name\":\"周宇琪\",\"id\":\"1338285518968438785\",\"age\":21}]', NULL, 0, 1313694379541635074, '2021-11-30 18:05:07', 1313694379541635074, '2021-11-30 18:05:07', '2021-11-30 18:02:51'); INSERT INTO `sys_logs` VALUES (1465622931110047745, '1', '测试模块-汽车信息-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/gentest/carinfo/v1/update', 'POST', 419, '[{\"carBrand\":\"123123\",\"carName\":\"自己_演示\",\"izUsable\":\"1\",\"izApi\":false,\"version\":0,\"createBy\":\"1313694379541635074\",\"carType\":\"123123\",\"izManual\":false,\"createTime\":1634289284000,\"produceData\":1633276800000,\"id\":\"1448940392903516161\"}]', NULL, 0, 1313694379541635074, '2021-11-30 18:05:11', 1313694379541635074, '2021-11-30 18:05:11', '2021-11-30 18:02:56'); -INSERT INTO `sys_logs` VALUES (1465624723692662786, '1', '开发工具-开发向导-代码模板-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/generator/template/v1/updateAndDetail', 'POST', 4967, '[{\"izApi\":false,\"remark\":\"默认Form表单\",\"updateTime\":1634109206000,\"version\":32,\"tableType\":\"0\",\"tempName\":\"Form表单\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1622204636000,\"updateBy\":\"1313694379541635074\",\"detailList\":[{\"fileName\":\"${model.tableHumpName}Entity.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/entity\",\"izManual\":false,\"ignoreFileName\":\"1\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).entity;\\n#end\\n\\n#for(pkg : data.model.entityPkgList)\\nimport #(pkg);\\n#end\\nimport com.baomidou.mybatisplus.annotation.FieldStrategy;\\nimport com.baomidou.mybatisplus.annotation.TableField;\\nimport com.baomidou.mybatisplus.annotation.TableLogic;\\nimport lombok.Data;\\nimport lombok.EqualsAndHashCode;\\nimport org.opsli.core.base.entity.BaseEntity;\\n\\n/**\\n * #(data.codeTitle) Entity\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Data\\n@EqualsAndHashCode(callSuper = false)\\npublic class #(data.model.tableHumpName) extends BaseEntity {\\n\\n\\n #for(column : data.model.columnList)\\n ### 不等于 删除字段 和 不等于 租户字段放入上边\\n #if(column.fieldHumpName != \\\"deleted\\\" && column.fieldHumpName != \\\"tenantId\\\")\\n /** #(column.fieldComments) */\\n #if(!column.izNotNull)\\n @TableField(updateStrategy = FieldStrategy.IGNORED)\\n #end\\n private #(column.javaType) #(column.fieldHumpName);\\n\\n #end\\n #end\\n\\n // ========================================\\n\\n ### 专门处理 删除字段 和 租户字段\\n #for(column : data.model.columnList)\\n #if(column.fieldHumpName == \\\"deleted\\\")\\n /** 逻辑删除字段 */\\n @TableLogic\\n private Integer deleted;\\n #else if(column.fieldHumpName == \\\"tenantId\\\")\\n /** 多租户字段 */\\n private String tenantId;\\n #end\\n\\n #end\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}Mapper.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/mapper\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).mapper;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).mapper;\\n#end\\n\\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\\nimport org.apache.ibatis.annotations.Mapper;\\nimport org.apache.ibatis.annotations.Param;\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\n#end\\n\\n/**\\n * #(data.codeTitle) Mapper\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Mapper\\npublic interface #(data.model.tableHumpName)Mapper extends BaseMapper<#(data.model.tableHumpName)> {\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}Mapper.xml\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/mapper/xml\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n\\n#else\\n\\n#end\\n\\n\\n\"},{\"fileName\":\"${model.tableHumpName}Model.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"org/opsli/api/wrapper/${moduleName}/${subModuleName}\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName);\\n#else\\npackage #(apiPath).wrapper.#(data.moduleName);\\n#end\\n\\n#for(pkg : data.model.entityPkgList)\\nimport #(pkg);\\n#end\\nimport com.alibaba.excel.annotation.ExcelProperty;\\nimport io.swagger.annotations.ApiModelProperty;\\nimport lombok.Data;\\nimport lombok.EqualsAndHashCode;\\nimport #(apiPath).base.warpper.ApiWrapper;\\nimport org.opsli.common.annotation.validator.Validator;\\nimport org.opsli.common.annotation.validator.ValidatorLenMax;\\nimport org.opsli.common.annotation.validator.ValidatorLenMin;\\nimport org.opsli.common.enums.ValidatorType;\\nimport org.opsli.plugins.excel.annotation.ExcelInfo;\\nimport com.fasterxml.jackson.annotation.JsonFormat;\\nimport org.springframework.format.annotation.DateTimeFormat;\\n\\n/**\\n* #(data.codeTitle) Model\\n*\\n* @author #(data.authorName)\\n* @date #(currTime)\\n*/\\n@Data\\n@EqualsAndHashCode(callSuper = false)\\npublic class #(data.model.tableHumpName)Model extends ApiWrapper {\\n\\n #for(column : data.model.columnList)\\n ### 不等于 删除字段 和 不等于 租户字段放入上边\\n #if(column.fieldHumpName != \\\"deleted\\\" && column.fieldHumpName != \\\"tenantId\\\")\\n /** #(column.fieldComments) */\\n @ApiModelProperty(value = \\\"#(column.fieldComments)\\\")\\n @ExcelProperty(value = \\\"#(column.fieldComments)\\\", order = #(column.sort))\\n #if(column.dictTypeCode != null && column.dictTypeCode != \\\"\\\")\\n @ExcelInfo( dictType = \\\"#(column.dictTypeCode)\\\" )\\n #else\\n @ExcelInfo\\n #end\\n #if(column.validateTypeAndCommaList != null && column.validateTypeAndCommaList.size() > 0)\\n @Validator({\\n #for(typeAndComma : column.validateTypeAndCommaList)\\n ValidatorType.#(typeAndComma)\\n #end\\n })\\n #end\\n #if(column.fieldLength != null && column.fieldLength > 0)\\n #if(column.fieldPrecision != null && column.fieldPrecision > 0)\\n @ValidatorLenMax(#(column.fieldLength+column.fieldPrecision))\\n #else\\n @ValidatorLenMax(#(column.fieldLength))\\n #end\\n #end\\n ### 日期处理\\n #if(column.javaType == \\\"Date\\\")\\n #if(column.showType == \\\"4\\\")\\n @JsonFormat(timezone = \\\"GMT+8\\\", pattern = \\\"yyyy-MM-dd\\\")\\n @DateTimeFormat(pattern = \\\"yyyy-MM-dd\\\")\\n #else\\n @JsonFormat(timezone = \\\"GMT+8\\\", pattern = \\\"yyyy-MM-dd HH:mm:ss\\\")\\n @DateTimeFormat(pattern = \\\"yyyy-MM-dd HH:mm:ss\\\")\\n #end\\n #end\\n private #(column.javaType) #(column.fieldHumpName);\\n\\n #end\\n #end\\n\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}RestApi.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"org/opsli/api/web/${moduleName}/${subModuleName}\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(apiPath).web.#(data.moduleName+\\\".\\\"+data.subModuleName);\\n#else\\npackage #(apiPath).web.#(data.moduleName);\\n#end\\n\\nimport #(apiPath).base.result.ResultVo;\\nimport org.springframework.web.bind.annotation.GetMapping;\\nimport org.springframework.web.bind.annotation.PostMapping;\\nimport org.springframework.web.bind.annotation.RequestBody;\\nimport org.springframework.web.bind.annotation.RequestParam;\\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\\nimport javax.servlet.http.HttpServletRequest;\\nimport javax.servlet.http.HttpServletResponse;\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\n#else\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\n#end\\n\\n\\n/**\\n * #(data.codeTitle) Api\\n *\\n * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping\\n * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起\\n *\\n * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\npublic interface #(data.model.tableHumpName)RestApi {\\n\\n /** 标题 */\\n String TITLE = \\\"#(data.codeTitle)\\\";\\n /** 子标题 */\\n String SUB_TITLE = \\\"#(data.codeTitleBrief)\\\";\\n\\n /**\\n * #(data.codeTitle) 查一条\\n * @param model 模型\\n * @return ResultVo\\n */\\n @GetMapping(\\\"/get\\\")\\n ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model);\\n\\n /**\\n * #(data.codeTitle) 查询分页\\n * @param pageNo 当前页\\n * @param pageSize 每页条数\\n * @param request request\\n * @return ResultVo\\n */\\n @GetMapping(\\\"/findPage\\\")\\n ResultVo findPage(\\n @RequestParam(name = \\\"pageNo\\\", defaultValue = \\\"1\\\") Integer pageNo,\\n @RequestParam(name = \\\"pageSize\\\", defaultValue = \\\"10\\\") Integer pageSize,\\n HttpServletRequest request\\n );\\n\\n /**\\n * #(data.codeTitle) 新增\\n * @param model 模型\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/insert\\\")\\n ResultVo insert(@RequestBody #(data.model.tableHumpName)Model model);\\n\\n /**\\n * #(data.codeTitle) 修改\\n * @param model 模型\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/update\\\")\\n ResultVo update(@RequestBody #(data.model.tableHumpName)Model model);\\n\\n /**\\n * #(data.codeTitle) 删除\\n * @param id ID\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/del\\\")\\n ResultVo del(String id);\\n\\n /**\\n * #(data.codeTitle) 批量删除\\n * @param ids ID 数组\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/delAll\\\")\\n ResultVo delAll(String ids);\\n\\n /**\\n * #(data.codeTitle) Excel 导出\\n *\\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\\n * 因为在 导出不成功时,需要推送错误信息,\\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\\n * response 推送 javascript代码 alert 提示报错信息\\n *\\n * @param request request\\n * @param response response\\n */\\n @GetMapping(\\\"/exportExcel\\\")\\n void exportExcel(HttpServletRequest request, HttpServletResponse response);\\n\\n /**\\n * #(data.codeTitle) Excel 导入\\n * @param request 文件流 request\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/importExcel\\\")\\n ResultVo importExcel(MultipartHttpServletRequest request);\\n\\n /**\\n * #(data.codeTitle) Excel 下载导入模版\\n * @param response response\\n */\\n @GetMapping(\\\"/importExcel/template\\\")\\n void importTemplate(HttpServletResponse response);\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}RestController.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/web\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).web;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).web;\\n#end\\n\\nimport cn.hutool.core.util.ReflectUtil;\\nimport cn.hutool.core.convert.Convert;\\nimport io.swagger.annotations.Api;\\nimport io.swagger.annotations.ApiOperation;\\nimport lombok.extern.slf4j.Slf4j;\\nimport org.opsli.common.annotation.RequiresPermissionsCus;\\nimport org.apache.shiro.authz.annotation.RequiresPermissions;\\nimport #(apiPath).base.result.ResultVo;\\nimport org.opsli.common.annotation.ApiRestController;\\nimport org.opsli.common.annotation.EnableLog;\\nimport org.opsli.core.base.controller.BaseRestController;\\nimport org.opsli.core.persistence.Page;\\nimport org.opsli.core.persistence.querybuilder.QueryBuilder;\\nimport org.opsli.core.persistence.querybuilder.WebQueryBuilder;\\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\\nimport javax.servlet.http.HttpServletRequest;\\nimport javax.servlet.http.HttpServletResponse;\\nimport java.lang.reflect.Method;\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\\nimport #(apiPath).web.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)RestApi;\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\\nimport #(apiPath).web.#(data.moduleName).#(data.model.tableHumpName)RestApi;\\n#end\\n\\n/**\\n * #(data.codeTitle) Controller\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Api(tags = #(data.model.tableHumpName)RestApi.TITLE)\\n@Slf4j\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n@ApiRestController(\\\"/#(data.moduleName)/#(data.subModuleName)/{ver}\\\")\\n#else\\n@ApiRestController(\\\"/#(data.moduleName)/{ver}\\\")\\n#end\\npublic class #(data.model.tableHumpName)RestController extends BaseRestController<#(data.model.tableHumpName), #(data.model.tableHumpName)Model, I#(data.model.tableHumpName)Service>\\n implements #(data.model.tableHumpName)RestApi {\\n\\n\\n /**\\n * #(data.codeTitleBrief) 查一条\\n * @param model 模型\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"获得单条#(data.codeTitleBrief)\\\", notes = \\\"获得单条#(data.codeTitleBrief) - ID\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_select\\\")\\n #end\\n @Override\\n public ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model) {\\n // 如果系统内部调用 则直接查数据库\\n if(model != null && model.getIzApi() != null && model.getIzApi()){\\n model = IService.get(model);\\n }\\n return ResultVo.success(model);\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 查询分页\\n * @param pageNo 当前页\\n * @param pageSize 每页条数\\n * @param request request\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"获得分页数据\\\", notes = \\\"获得分页数据 - 查询构造器\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_select\\\")\\n #end\\n @Override\\n public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {\\n\\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\\n Page<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> page = new Page<>(pageNo, pageSize);\\n page.setQueryWrapper(queryBuilder.build());\\n page = IService.findPage(page);\\n\\n return ResultVo.success(page.getPageData());\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 新增\\n * @param model 模型\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"新增#(data.codeTitleBrief)数据\\\", notes = \\\"新增#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_insert\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_insert\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo insert(#(data.model.tableHumpName)Model model) {\\n // 调用新增方法\\n IService.insert(model);\\n return ResultVo.success(\\\"新增#(data.codeTitleBrief)成功\\\");\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 修改\\n * @param model 模型\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"修改#(data.codeTitleBrief)数据\\\", notes = \\\"修改#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_update\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo update(#(data.model.tableHumpName)Model model) {\\n // 调用修改方法\\n IService.update(model);\\n return ResultVo.success(\\\"修改#(data.codeTitleBrief)成功\\\");\\n }\\n\\n\\n /**\\n * #(data.codeTitleBrief) 删除\\n * @param id ID\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"删除#(data.codeTitleBrief)数据\\\", notes = \\\"删除#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_update\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo del(String id){\\n IService.delete(id);\\n return ResultVo.success(\\\"删除#(data.codeTitleBrief)成功\\\");\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 批量删除\\n * @param ids ID 数组\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"批量删除#(data.codeTitleBrief)数据\\\", notes = \\\"批量删除#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_update\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo delAll(String ids){\\n String[] idArray = Convert.toStrArray(ids);\\n IService.deleteAll(idArray);\\n return ResultVo.success(\\\"批量删除#(data.codeTitleBrief)成功\\\");\\n }\\n\\n\\n /**\\n * #(data.codeTitleBrief) Excel 导出\\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\\n *\\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\\n * 因为在 导出不成功时,需要推送错误信息,\\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\\n * response 推送 javascript代码 alert 提示报错信息\\n *\\n * @param request request\\n * @param response response\\n */\\n @ApiOperation(value = \\\"导出Excel\\\", notes = \\\"导出Excel\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_export\\\")\\n #else\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_export\\\")\\n #end\\n @EnableLog\\n @Override\\n public void exportExcel(HttpServletRequest request, HttpServletResponse response) {\\n // 当前方法\\n Method method = ReflectUtil.getMethodByName(this.getClass(), \\\"exportExcel\\\");\\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\\n super.excelExport(#(data.model.tableHumpName)RestApi.SUB_TITLE, queryBuilder.build(), response, method);\\n }\\n\\n /**\\n * #(data.codeTitleBrief) Excel 导入\\n * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解\\n * @param request 文件流 request\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"导入Excel\\\", notes = \\\"导入Excel\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_import\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo importExcel(MultipartHttpServletRequest request) {\\n return super.importExcel(request);\\n }\\n\\n /**\\n * #(data.codeTitleBrief) Excel 下载导入模版\\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\\n * @param response response\\n */\\n @ApiOperation(value = \\\"导出Excel模版\\\", notes = \\\"导出Excel模版\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\\\")\\n #else\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_import\\\")\\n #end\\n @Override\\n public void importTemplate(HttpServletResponse response) {\\n // 当前方法\\n Method method = ReflectUtil.getMethodByName(this.getClass(), \\\"importTemplate\\\");\\n super.importTemplate(#(data.model.tableHumpName)RestApi.SUB_TITLE, response, method);\\n }\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}ServiceImpl.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/service/impl\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service.impl;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).service.impl;\\n#end\\n\\n\\nimport org.springframework.beans.factory.annotation.Autowired;\\nimport org.springframework.stereotype.Service;\\nimport org.springframework.transaction.annotation.Transactional;\\nimport org.opsli.core.base.service.impl.CrudServiceImpl;\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).mapper.#(data.model.tableHumpName)Mapper;\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\\nimport #(data.packageName+\\\".\\\"+data.moduleName).mapper.#(data.model.tableHumpName)Mapper;\\n#end\\n\\n\\n/**\\n * #(data.codeTitle) Service Impl\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Service\\npublic class #(data.model.tableHumpName)ServiceImpl extends CrudServiceImpl<#(data.model.tableHumpName)Mapper, #(data.model.tableHumpName), #(data.model.tableHumpName)Model>\\n implements I#(data.model.tableHumpName)Service {\\n\\n @Autowired(required = false)\\n private #(data.model.tableHumpName)Mapper mapper;\\n\\n}\"},{\"fileName\":\"I${model.tableHumpName}Service.java\",\"izApi\":false,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/service\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).service;\\n#end\\n\\nimport org.opsli.core.base.service.interfaces.CrudServiceInterface;\\n\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\n#end\\n\\n/**\\n * #(data.codeTitle) Service\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\npublic interface I#(data.model.tableHumpName)Service extends CrudServiceInterface<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> {\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}ManagementApi.js\",\"izApi\":false,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/api/${moduleName}/${subModuleName}\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"import request from \\\"@/utils/request\\\";\\nimport { downloadFileByData } from \\\"@/utils/download\\\";\\n\\nexport function getList(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/findPage\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/findPage\\\",\\n #end\\n method: \\\"get\\\",\\n params: data,\\n });\\n}\\n\\nexport function doInsert(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/insert\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/insert\\\",\\n #end\\n method: \\\"post\\\",\\n data,\\n });\\n}\\n\\nexport function doUpdate(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/update\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/update\\\",\\n #end\\n method: \\\"post\\\",\\n data,\\n });\\n}\\n\\nexport function doDelete(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/del\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/del\\\",\\n #end\\n method: \\\"post\\\",\\n params: data,\\n });\\n}\\n\\nexport function doDeleteAll(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/delAll\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/delAll\\\",\\n #end\\n method: \\\"post\\\",\\n params: data,\\n });\\n}\\n\\n/**\\n * 导出Excel 目前只支持一层参数传递\\n * @param data\\n * @returns file\\n */\\nexport function doExportExcel(data) {\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n let requestURL = \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/exportExcel\\\";\\n #else\\n let requestURL = \\\"/api/v1/#(data.moduleName)/exportExcel\\\";\\n #end\\n // 下载文件\\n downloadFileByData(requestURL, data);\\n}\\n\\n/**\\n * 下载模版\\n * @returns file\\n */\\nexport function doDownloadTemplate() {\\n let data = {};\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n let requestURL = \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/importExcel/template\\\";\\n #else\\n let requestURL = \\\"/api/v1/#(data.moduleName)/importExcel/template\\\";\\n #end\\n // 下载文件\\n downloadFileByData(requestURL, data);\\n}\\n\\n/**\\n * 导入Excel\\n * @returns file\\n */\\nexport function doImportExcel(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/importExcel\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/importExcel\\\",\\n #end\\n method: \\\"post\\\",\\n // 最长超时时间 3 分钟\\n timeout: 180000,\\n headers: {\\n \\\"Content-Type\\\": \\\"multipart/form-data\\\"\\n },\\n data,\\n });\\n}\"},{\"fileName\":\"${model.tableHumpName}ManagementEdit.vue\",\"izApi\":false,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/views/modules/${moduleName}/${subModuleName}/components\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"\\n\\n\\n\"},{\"fileName\":\"${model.tableHumpName}ManagementImport.vue\",\"izApi\":false,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/views/modules/${moduleName}/${subModuleName}/components\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"\\n\\n\\n\"},{\"fileName\":\"index.vue\",\"izApi\":false,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/views/modules/${moduleName}/${subModuleName}\",\"izManual\":false,\"ignoreFileName\":\"0\",\"fileContent\":\"\\n\\n\\n\"}],\"id\":\"1398253704724828162\"}]', NULL, 0, 1465171199435362305, '2021-11-30 18:12:19', 1465171199435362305, '2021-11-30 18:12:19', '2021-11-30 18:10:04'); -INSERT INTO `sys_logs` VALUES (1465624746056691713, '1', '开发工具-开发向导-代码模板-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/generator/template/v1/updateAndDetail', 'POST', 290, '[{\"izApi\":false,\"remark\":\"默认Form表单\",\"updateTime\":1634109206000,\"version\":32,\"tableType\":\"0\",\"tempName\":\"Form表单\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1622204636000,\"updateBy\":\"1313694379541635074\",\"detailList\":[{\"fileName\":\"${model.tableHumpName}Entity.java\",\"izApi\":false,\"updateTime\":1634109206000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/entity\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109206000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"1\",\"id\":\"1448185088918077441\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).entity;\\n#end\\n\\n#for(pkg : data.model.entityPkgList)\\nimport #(pkg);\\n#end\\nimport com.baomidou.mybatisplus.annotation.FieldStrategy;\\nimport com.baomidou.mybatisplus.annotation.TableField;\\nimport com.baomidou.mybatisplus.annotation.TableLogic;\\nimport lombok.Data;\\nimport lombok.EqualsAndHashCode;\\nimport org.opsli.core.base.entity.BaseEntity;\\n\\n/**\\n * #(data.codeTitle) Entity\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Data\\n@EqualsAndHashCode(callSuper = false)\\npublic class #(data.model.tableHumpName) extends BaseEntity {\\n\\n\\n #for(column : data.model.columnList)\\n ### 不等于 删除字段 和 不等于 租户字段放入上边\\n #if(column.fieldHumpName != \\\"deleted\\\" && column.fieldHumpName != \\\"tenantId\\\")\\n /** #(column.fieldComments) */\\n #if(!column.izNotNull)\\n @TableField(updateStrategy = FieldStrategy.IGNORED)\\n #end\\n private #(column.javaType) #(column.fieldHumpName);\\n\\n #end\\n #end\\n\\n // ========================================\\n\\n ### 专门处理 删除字段 和 租户字段\\n #for(column : data.model.columnList)\\n #if(column.fieldHumpName == \\\"deleted\\\")\\n /** 逻辑删除字段 */\\n @TableLogic\\n private Integer deleted;\\n #else if(column.fieldHumpName == \\\"tenantId\\\")\\n /** 多租户字段 */\\n private String tenantId;\\n #end\\n\\n #end\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}Mapper.java\",\"izApi\":false,\"updateTime\":1634109206000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/mapper\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109206000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185089241038850\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).mapper;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).mapper;\\n#end\\n\\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\\nimport org.apache.ibatis.annotations.Mapper;\\nimport org.apache.ibatis.annotations.Param;\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\n#end\\n\\n/**\\n * #(data.codeTitle) Mapper\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Mapper\\npublic interface #(data.model.tableHumpName)Mapper extends BaseMapper<#(data.model.tableHumpName)> {\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}Mapper.xml\",\"izApi\":false,\"updateTime\":1634109206000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/mapper/xml\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109206000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185089689829378\",\"fileContent\":\"\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n\\n#else\\n\\n#end\\n\\n\\n\"},{\"fileName\":\"${model.tableHumpName}Model.java\",\"izApi\":false,\"updateTime\":1634109206000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"org/opsli/api/wrapper/${moduleName}/${subModuleName}\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109206000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185090205728769\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName);\\n#else\\npackage #(apiPath).wrapper.#(data.moduleName);\\n#end\\n\\n#for(pkg : data.model.entityPkgList)\\nimport #(pkg);\\n#end\\nimport com.alibaba.excel.annotation.ExcelProperty;\\nimport io.swagger.annotations.ApiModelProperty;\\nimport lombok.Data;\\nimport lombok.EqualsAndHashCode;\\nimport #(apiPath).base.warpper.ApiWrapper;\\nimport org.opsli.common.annotation.validator.Validator;\\nimport org.opsli.common.annotation.validator.ValidatorLenMax;\\nimport org.opsli.common.annotation.validator.ValidatorLenMin;\\nimport org.opsli.common.enums.ValidatorType;\\nimport org.opsli.plugins.excel.annotation.ExcelInfo;\\nimport com.fasterxml.jackson.annotation.JsonFormat;\\nimport org.springframework.format.annotation.DateTimeFormat;\\n\\n/**\\n* #(data.codeTitle) Model\\n*\\n* @author #(data.authorName)\\n* @date #(currTime)\\n*/\\n@Data\\n@EqualsAndHashCode(callSuper = false)\\npublic class #(data.model.tableHumpName)Model extends ApiWrapper {\\n\\n #for(column : data.model.columnList)\\n ### 不等于 删除字段 和 不等于 租户字段放入上边\\n #if(column.fieldHumpName != \\\"deleted\\\" && column.fieldHumpName != \\\"tenantId\\\")\\n /** #(column.fieldComments) */\\n @ApiModelProperty(value = \\\"#(column.fieldComments)\\\")\\n @ExcelProperty(value = \\\"#(column.fieldComments)\\\", order = #(column.sort))\\n #if(column.dictTypeCode != null && column.dictTypeCode != \\\"\\\")\\n @ExcelInfo( dictType = \\\"#(column.dictTypeCode)\\\" )\\n #else\\n @ExcelInfo\\n #end\\n #if(column.validateTypeAndCommaList != null && column.validateTypeAndCommaList.size() > 0)\\n @Validator({\\n #for(typeAndComma : column.validateTypeAndCommaList)\\n ValidatorType.#(typeAndComma)\\n #end\\n })\\n #end\\n #if(column.fieldLength != null && column.fieldLength > 0)\\n #if(column.fieldPrecision != null && column.fieldPrecision > 0)\\n @ValidatorLenMax(#(column.fieldLength+column.fieldPrecision))\\n #else\\n @ValidatorLenMax(#(column.fieldLength))\\n #end\\n #end\\n ### 日期处理\\n #if(column.javaType == \\\"Date\\\")\\n #if(column.showType == \\\"4\\\")\\n @JsonFormat(timezone = \\\"GMT+8\\\", pattern = \\\"yyyy-MM-dd\\\")\\n @DateTimeFormat(pattern = \\\"yyyy-MM-dd\\\")\\n #else\\n @JsonFormat(timezone = \\\"GMT+8\\\", pattern = \\\"yyyy-MM-dd HH:mm:ss\\\")\\n @DateTimeFormat(pattern = \\\"yyyy-MM-dd HH:mm:ss\\\")\\n #end\\n #end\\n private #(column.javaType) #(column.fieldHumpName);\\n\\n #end\\n #end\\n\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}RestApi.java\",\"izApi\":false,\"updateTime\":1634109207000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"org/opsli/api/web/${moduleName}/${subModuleName}\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109207000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185092231577601\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(apiPath).web.#(data.moduleName+\\\".\\\"+data.subModuleName);\\n#else\\npackage #(apiPath).web.#(data.moduleName);\\n#end\\n\\nimport #(apiPath).base.result.ResultVo;\\nimport org.springframework.web.bind.annotation.GetMapping;\\nimport org.springframework.web.bind.annotation.PostMapping;\\nimport org.springframework.web.bind.annotation.RequestBody;\\nimport org.springframework.web.bind.annotation.RequestParam;\\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\\nimport javax.servlet.http.HttpServletRequest;\\nimport javax.servlet.http.HttpServletResponse;\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\n#else\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\n#end\\n\\n\\n/**\\n * #(data.codeTitle) Api\\n *\\n * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping\\n * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起\\n *\\n * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\npublic interface #(data.model.tableHumpName)RestApi {\\n\\n /** 标题 */\\n String TITLE = \\\"#(data.codeTitle)\\\";\\n /** 子标题 */\\n String SUB_TITLE = \\\"#(data.codeTitleBrief)\\\";\\n\\n /**\\n * #(data.codeTitle) 查一条\\n * @param model 模型\\n * @return ResultVo\\n */\\n @GetMapping(\\\"/get\\\")\\n ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model);\\n\\n /**\\n * #(data.codeTitle) 查询分页\\n * @param pageNo 当前页\\n * @param pageSize 每页条数\\n * @param request request\\n * @return ResultVo\\n */\\n @GetMapping(\\\"/findPage\\\")\\n ResultVo findPage(\\n @RequestParam(name = \\\"pageNo\\\", defaultValue = \\\"1\\\") Integer pageNo,\\n @RequestParam(name = \\\"pageSize\\\", defaultValue = \\\"10\\\") Integer pageSize,\\n HttpServletRequest request\\n );\\n\\n /**\\n * #(data.codeTitle) 新增\\n * @param model 模型\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/insert\\\")\\n ResultVo insert(@RequestBody #(data.model.tableHumpName)Model model);\\n\\n /**\\n * #(data.codeTitle) 修改\\n * @param model 模型\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/update\\\")\\n ResultVo update(@RequestBody #(data.model.tableHumpName)Model model);\\n\\n /**\\n * #(data.codeTitle) 删除\\n * @param id ID\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/del\\\")\\n ResultVo del(String id);\\n\\n /**\\n * #(data.codeTitle) 批量删除\\n * @param ids ID 数组\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/delAll\\\")\\n ResultVo delAll(String ids);\\n\\n /**\\n * #(data.codeTitle) Excel 导出\\n *\\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\\n * 因为在 导出不成功时,需要推送错误信息,\\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\\n * response 推送 javascript代码 alert 提示报错信息\\n *\\n * @param request request\\n * @param response response\\n */\\n @GetMapping(\\\"/exportExcel\\\")\\n void exportExcel(HttpServletRequest request, HttpServletResponse response);\\n\\n /**\\n * #(data.codeTitle) Excel 导入\\n * @param request 文件流 request\\n * @return ResultVo\\n */\\n @PostMapping(\\\"/importExcel\\\")\\n ResultVo importExcel(MultipartHttpServletRequest request);\\n\\n /**\\n * #(data.codeTitle) Excel 下载导入模版\\n * @param response response\\n */\\n @GetMapping(\\\"/importExcel/template\\\")\\n void importTemplate(HttpServletResponse response);\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}RestController.java\",\"izApi\":false,\"updateTime\":1634109207000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/web\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109207000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185095272448002\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).web;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).web;\\n#end\\n\\nimport cn.hutool.core.util.ReflectUtil;\\nimport cn.hutool.core.convert.Convert;\\nimport io.swagger.annotations.Api;\\nimport io.swagger.annotations.ApiOperation;\\nimport lombok.extern.slf4j.Slf4j;\\nimport org.opsli.common.annotation.RequiresPermissionsCus;\\nimport org.apache.shiro.authz.annotation.RequiresPermissions;\\nimport #(apiPath).base.result.ResultVo;\\nimport org.opsli.common.annotation.ApiRestController;\\nimport org.opsli.common.annotation.EnableLog;\\nimport org.opsli.core.base.controller.BaseRestController;\\nimport org.opsli.core.persistence.Page;\\nimport org.opsli.core.persistence.querybuilder.QueryBuilder;\\nimport org.opsli.core.persistence.querybuilder.WebQueryBuilder;\\nimport org.springframework.web.multipart.MultipartHttpServletRequest;\\nimport javax.servlet.http.HttpServletRequest;\\nimport javax.servlet.http.HttpServletResponse;\\nimport java.lang.reflect.Method;\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\\nimport #(apiPath).web.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)RestApi;\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\\nimport #(apiPath).web.#(data.moduleName).#(data.model.tableHumpName)RestApi;\\n#end\\n\\n/**\\n * #(data.codeTitle) Controller\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Api(tags = #(data.model.tableHumpName)RestApi.TITLE)\\n@Slf4j\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n@ApiRestController(\\\"/#(data.moduleName)/#(data.subModuleName)/{ver}\\\")\\n#else\\n@ApiRestController(\\\"/#(data.moduleName)/{ver}\\\")\\n#end\\npublic class #(data.model.tableHumpName)RestController extends BaseRestController<#(data.model.tableHumpName), #(data.model.tableHumpName)Model, I#(data.model.tableHumpName)Service>\\n implements #(data.model.tableHumpName)RestApi {\\n\\n\\n /**\\n * #(data.codeTitleBrief) 查一条\\n * @param model 模型\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"获得单条#(data.codeTitleBrief)\\\", notes = \\\"获得单条#(data.codeTitleBrief) - ID\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_select\\\")\\n #end\\n @Override\\n public ResultVo<#(data.model.tableHumpName)Model> get(#(data.model.tableHumpName)Model model) {\\n // 如果系统内部调用 则直接查数据库\\n if(model != null && model.getIzApi() != null && model.getIzApi()){\\n model = IService.get(model);\\n }\\n return ResultVo.success(model);\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 查询分页\\n * @param pageNo 当前页\\n * @param pageSize 每页条数\\n * @param request request\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"获得分页数据\\\", notes = \\\"获得分页数据 - 查询构造器\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_select\\\")\\n #end\\n @Override\\n public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {\\n\\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\\n Page<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> page = new Page<>(pageNo, pageSize);\\n page.setQueryWrapper(queryBuilder.build());\\n page = IService.findPage(page);\\n\\n return ResultVo.success(page.getPageData());\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 新增\\n * @param model 模型\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"新增#(data.codeTitleBrief)数据\\\", notes = \\\"新增#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_insert\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_insert\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo insert(#(data.model.tableHumpName)Model model) {\\n // 调用新增方法\\n IService.insert(model);\\n return ResultVo.success(\\\"新增#(data.codeTitleBrief)成功\\\");\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 修改\\n * @param model 模型\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"修改#(data.codeTitleBrief)数据\\\", notes = \\\"修改#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_update\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo update(#(data.model.tableHumpName)Model model) {\\n // 调用修改方法\\n IService.update(model);\\n return ResultVo.success(\\\"修改#(data.codeTitleBrief)成功\\\");\\n }\\n\\n\\n /**\\n * #(data.codeTitleBrief) 删除\\n * @param id ID\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"删除#(data.codeTitleBrief)数据\\\", notes = \\\"删除#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_update\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo del(String id){\\n IService.delete(id);\\n return ResultVo.success(\\\"删除#(data.codeTitleBrief)成功\\\");\\n }\\n\\n /**\\n * #(data.codeTitleBrief) 批量删除\\n * @param ids ID 数组\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"批量删除#(data.codeTitleBrief)数据\\\", notes = \\\"批量删除#(data.codeTitleBrief)数据\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_update\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo delAll(String ids){\\n String[] idArray = Convert.toStrArray(ids);\\n IService.deleteAll(idArray);\\n return ResultVo.success(\\\"批量删除#(data.codeTitleBrief)成功\\\");\\n }\\n\\n\\n /**\\n * #(data.codeTitleBrief) Excel 导出\\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\\n *\\n * 导出时,Token认证和方法权限认证 全部都由自定义完成\\n * 因为在 导出不成功时,需要推送错误信息,\\n * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时\\n * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死\\n * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段\\n * response 推送 javascript代码 alert 提示报错信息\\n *\\n * @param request request\\n * @param response response\\n */\\n @ApiOperation(value = \\\"导出Excel\\\", notes = \\\"导出Excel\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_export\\\")\\n #else\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_export\\\")\\n #end\\n @EnableLog\\n @Override\\n public void exportExcel(HttpServletRequest request, HttpServletResponse response) {\\n // 当前方法\\n Method method = ReflectUtil.getMethodByName(this.getClass(), \\\"exportExcel\\\");\\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());\\n super.excelExport(#(data.model.tableHumpName)RestApi.SUB_TITLE, queryBuilder.build(), response, method);\\n }\\n\\n /**\\n * #(data.codeTitleBrief) Excel 导入\\n * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解\\n * @param request 文件流 request\\n * @return ResultVo\\n */\\n @ApiOperation(value = \\\"导入Excel\\\", notes = \\\"导入Excel\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\\\")\\n #else\\n @RequiresPermissions(\\\"#(data.moduleName.toLowerCase())_import\\\")\\n #end\\n @EnableLog\\n @Override\\n public ResultVo importExcel(MultipartHttpServletRequest request) {\\n return super.importExcel(request);\\n }\\n\\n /**\\n * #(data.codeTitleBrief) Excel 下载导入模版\\n * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解\\n * @param response response\\n */\\n @ApiOperation(value = \\\"导出Excel模版\\\", notes = \\\"导出Excel模版\\\")\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\\\")\\n #else\\n @RequiresPermissionsCus(\\\"#(data.moduleName.toLowerCase())_import\\\")\\n #end\\n @Override\\n public void importTemplate(HttpServletResponse response) {\\n // 当前方法\\n Method method = ReflectUtil.getMethodByName(this.getClass(), \\\"importTemplate\\\");\\n super.importTemplate(#(data.model.tableHumpName)RestApi.SUB_TITLE, response, method);\\n }\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}ServiceImpl.java\",\"izApi\":false,\"updateTime\":1634109208000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/service/impl\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109208000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185098657251330\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service.impl;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).service.impl;\\n#end\\n\\n\\nimport org.springframework.beans.factory.annotation.Autowired;\\nimport org.springframework.stereotype.Service;\\nimport org.springframework.transaction.annotation.Transactional;\\nimport org.opsli.core.base.service.impl.CrudServiceImpl;\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service.I#(data.model.tableHumpName)Service;\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).mapper.#(data.model.tableHumpName)Mapper;\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\nimport #(data.packageName+\\\".\\\"+data.moduleName).service.I#(data.model.tableHumpName)Service;\\nimport #(data.packageName+\\\".\\\"+data.moduleName).mapper.#(data.model.tableHumpName)Mapper;\\n#end\\n\\n\\n/**\\n * #(data.codeTitle) Service Impl\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\n@Service\\npublic class #(data.model.tableHumpName)ServiceImpl extends CrudServiceImpl<#(data.model.tableHumpName)Mapper, #(data.model.tableHumpName), #(data.model.tableHumpName)Model>\\n implements I#(data.model.tableHumpName)Service {\\n\\n @Autowired(required = false)\\n private #(data.model.tableHumpName)Mapper mapper;\\n\\n}\"},{\"fileName\":\"I${model.tableHumpName}Service.java\",\"izApi\":false,\"updateTime\":1634109209000,\"type\":\"0\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"${packageName}/${moduleName}/${subModuleName}/service\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109209000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185102641840129\",\"fileContent\":\"#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\npackage #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).service;\\n#else\\npackage #(data.packageName+\\\".\\\"+data.moduleName).service;\\n#end\\n\\nimport org.opsli.core.base.service.interfaces.CrudServiceInterface;\\n\\n\\n#if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\nimport #(data.packageName+\\\".\\\"+data.moduleName+\\\".\\\"+data.subModuleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName+\\\".\\\"+data.subModuleName).#(data.model.tableHumpName)Model;\\n#else\\nimport #(data.packageName+\\\".\\\"+data.moduleName).entity.#(data.model.tableHumpName);\\nimport #(apiPath).wrapper.#(data.moduleName).#(data.model.tableHumpName)Model;\\n#end\\n\\n/**\\n * #(data.codeTitle) Service\\n *\\n * @author #(data.authorName)\\n * @date #(currTime)\\n */\\npublic interface I#(data.model.tableHumpName)Service extends CrudServiceInterface<#(data.model.tableHumpName), #(data.model.tableHumpName)Model> {\\n\\n}\"},{\"fileName\":\"${model.tableHumpName}ManagementApi.js\",\"izApi\":false,\"updateTime\":1634109210000,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/api/${moduleName}/${subModuleName}\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109210000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185107255574530\",\"fileContent\":\"import request from \\\"@/utils/request\\\";\\nimport { downloadFileByData } from \\\"@/utils/download\\\";\\n\\nexport function getList(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/findPage\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/findPage\\\",\\n #end\\n method: \\\"get\\\",\\n params: data,\\n });\\n}\\n\\nexport function doInsert(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/insert\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/insert\\\",\\n #end\\n method: \\\"post\\\",\\n data,\\n });\\n}\\n\\nexport function doUpdate(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/update\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/update\\\",\\n #end\\n method: \\\"post\\\",\\n data,\\n });\\n}\\n\\nexport function doDelete(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/del\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/del\\\",\\n #end\\n method: \\\"post\\\",\\n params: data,\\n });\\n}\\n\\nexport function doDeleteAll(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/delAll\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/delAll\\\",\\n #end\\n method: \\\"post\\\",\\n params: data,\\n });\\n}\\n\\n/**\\n * 导出Excel 目前只支持一层参数传递\\n * @param data\\n * @returns file\\n */\\nexport function doExportExcel(data) {\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n let requestURL = \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/exportExcel\\\";\\n #else\\n let requestURL = \\\"/api/v1/#(data.moduleName)/exportExcel\\\";\\n #end\\n // 下载文件\\n downloadFileByData(requestURL, data);\\n}\\n\\n/**\\n * 下载模版\\n * @returns file\\n */\\nexport function doDownloadTemplate() {\\n let data = {};\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n let requestURL = \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/importExcel/template\\\";\\n #else\\n let requestURL = \\\"/api/v1/#(data.moduleName)/importExcel/template\\\";\\n #end\\n // 下载文件\\n downloadFileByData(requestURL, data);\\n}\\n\\n/**\\n * 导入Excel\\n * @returns file\\n */\\nexport function doImportExcel(data) {\\n return request({\\n #if(data.subModuleName != null && data.subModuleName != \\\"\\\")\\n url: \\\"/api/v1/#(data.moduleName)/#(data.subModuleName)/importExcel\\\",\\n #else\\n url: \\\"/api/v1/#(data.moduleName)/importExcel\\\",\\n #end\\n method: \\\"post\\\",\\n // 最长超时时间 3 分钟\\n timeout: 180000,\\n headers: {\\n \\\"Content-Type\\\": \\\"multipart/form-data\\\"\\n },\\n data,\\n });\\n}\"},{\"fileName\":\"${model.tableHumpName}ManagementEdit.vue\",\"izApi\":false,\"updateTime\":1634109212000,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/views/modules/${moduleName}/${subModuleName}/components\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109212000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185112708169729\",\"fileContent\":\"\\n\\n\\n\"},{\"fileName\":\"${model.tableHumpName}ManagementImport.vue\",\"izApi\":false,\"updateTime\":1634109213000,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/views/modules/${moduleName}/${subModuleName}/components\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109213000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185118160764930\",\"fileContent\":\"\\n\\n\\n\"},{\"fileName\":\"index.vue\",\"izApi\":false,\"updateTime\":1634109214000,\"type\":\"1\",\"version\":0,\"parentId\":\"1398253704724828162\",\"path\":\"src/views/modules/${moduleName}/${subModuleName}\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1634109214000,\"updateBy\":\"1313694379541635074\",\"ignoreFileName\":\"0\",\"id\":\"1448185124422860802\",\"fileContent\":\"\\n\\n\\n\"}],\"id\":\"1398253704724828162\"}]', NULL, 0, 1465171199435362305, '2021-11-30 18:12:24', 1465171199435362305, '2021-11-30 18:12:24', '2021-11-30 18:10:09'); INSERT INTO `sys_logs` VALUES (1465879903789035521, '1', '组织机构-用户管理-增加', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/system/user/v1/insert', 'POST', 1075, '[{\"no\":\"123123\",\"secretKey\":\"aubsfx07wtsv5ixvg570\",\"mobile\":\"15311111111\",\"izApi\":false,\"version\":0,\"izExistOrg\":\"0\",\"enableSwitchTenant\":\"0\",\"passwordLevel\":\"2\",\"realName\":\"租户管理员\",\"password\":\"2ac43879f3ac98b98fb97557f24b3ccb\",\"izTenantAdmin\":\"1\",\"izManual\":false,\"enable\":\"1\",\"tenantId\":\"1\",\"email\":\"meet.parker@foxmail.com\",\"username\":\"tenant\"}]', NULL, 0, 1, '2021-12-01 11:06:18', 1, '2021-12-01 11:06:18', '2021-12-01 11:04:04'); INSERT INTO `sys_logs` VALUES (1465879988480421889, '1', '组织机构-用户管理-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/system/user/v1/update', 'POST', 438, '[{\"no\":\"test_001\",\"mobile\":\"15311111111\",\"izApi\":false,\"avatar\":\"http://upload.bedebug.com/20211013/1635589382475625280EW3N.jpg\",\"version\":4,\"enableSwitchTenant\":\"0\",\"realName\":\"演示用户\",\"createBy\":\"1\",\"izTenantAdmin\":\"1\",\"izManual\":false,\"createTime\":1601997322000,\"tenantId\":\"1\",\"id\":\"1313694379541635074\",\"email\":\"meet.parker@foxmail.com\"}]', NULL, 0, 1, '2021-12-01 11:06:39', 1, '2021-12-01 11:06:39', '2021-12-01 11:04:24'); INSERT INTO `sys_logs` VALUES (1465880048194727938, '1', '组织机构-用户管理-修改', '', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', '/opsli-boot/api/system/user/v1/update', 'POST', 296, '[{\"no\":\"123123\",\"mobile\":\"15300000000\",\"izApi\":false,\"version\":0,\"enableSwitchTenant\":\"0\",\"realName\":\"租户管理员\",\"createBy\":\"1\",\"izTenantAdmin\":\"1\",\"izManual\":false,\"createTime\":1638327977000,\"tenantId\":\"1\",\"id\":\"1465879900211294210\",\"email\":\"meet.parker@foxmail.com\"}]', NULL, 0, 1, '2021-12-01 11:06:53', 1, '2021-12-01 11:06:53', '2021-12-01 11:04:39'); diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/ApiCryptoAsymmetric.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/LoginCrypto.java similarity index 81% rename from opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/ApiCryptoAsymmetric.java rename to opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/LoginCrypto.java index 8dbfbd5ba230d1884d677f34efecd850cb2618c4..6ab9e2aa9d0a0ae38787eeac554ab97fc0b4f39e 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/ApiCryptoAsymmetric.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/LoginCrypto.java @@ -19,7 +19,9 @@ package org.opsli.common.annotation; import java.lang.annotation.*; /** - * Api非对称加解密 + * 登录加解密 + * 入参 非对称 公钥加密 私钥解密 + * 出参 对称 公要加密 公要解密 * * @author Parker * @date 2021年5月18日14:46:02 @@ -27,15 +29,9 @@ import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented -public @interface ApiCryptoAsymmetric { +public @interface LoginCrypto { /** 加密启用状态 */ boolean enable() default true; - /** 请求解密 */ - boolean requestDecrypt() default true; - - /** 返回加密 */ - boolean responseEncrypt() default true; - } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/CacheConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/CacheConstants.java index 1d2650ec4f57518188c0a90f5c14a955f5b1fe35..e3030294a773cb82128b10c913ef950980be9d0c 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/CacheConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/CacheConstants.java @@ -21,14 +21,16 @@ package org.opsli.common.constants; * @author Parker * @date 2020-09-22 17:07 */ -public interface CacheConstants { +public final class CacheConstants { - String PREFIX_NAME = "opsli"; + public static final String PREFIX_NAME = "opsli"; /** Ehcache 缓存存放空间 */ - String EHCACHE_SPACE = "timed"; + public static final String EHCACHE_SPACE = "timed"; /** 热数据前缀 */ - String HOT_DATA_PREFIX = "hot_data"; + public static final String HOT_DATA_PREFIX = "hot_data"; + + private CacheConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/DictConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/DictConstants.java deleted file mode 100644 index 5cfe386f2711cf86aa2aad85266733ef8ee0cd8c..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/DictConstants.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.common.constants; - -/** - * 字典缓存 常量 - * - * @author Parker - * @date 2020-09-16 17:42 - */ -public interface DictConstants { - - /** 缓存前缀 NAME */ - String CACHE_PREFIX_NAME = "dict:name:"; - - /** 缓存前缀 VALUE*/ - String CACHE_PREFIX_VALUE = "dict:value:"; - - /** 缓存前缀 LIST*/ - String CACHE_PREFIX_LIST = "dict:list:"; - -} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MenuConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MenuConstants.java index c9136a1cd24560e7a590dfcd6a7caf3a22d8ee38..5ec14da43c95502515c202527f7d349454e43768 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MenuConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MenuConstants.java @@ -21,18 +21,20 @@ package org.opsli.common.constants; * @author Parker * @date 2021年3月10日15:50:16 */ -public interface MenuConstants { +public final class MenuConstants { /** 菜单根节点ID */ - String GEN_ID = "0"; + public static final String GEN_ID = "0"; /** 菜单类型 */ - String MENU = "1"; + public static final String MENU = "1"; /** 按钮类型 */ - String BUTTON = "2"; + public static final String BUTTON = "2"; /** 外链类型 */ - String EXTERNAL = "3"; + public static final String EXTERNAL = "3"; + + private MenuConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MyBatisConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MyBatisConstants.java index 893209c631f4c1443d9aaa251d3b118e453d4443..c418f11b5b4b65e9b4944f0d2db4a9f05d5baada 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MyBatisConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/MyBatisConstants.java @@ -23,35 +23,37 @@ package org.opsli.common.constants; * @author Parker * @date 2020-09-16 17:42 */ -public interface MyBatisConstants { +public final class MyBatisConstants { /** 逻辑删除值 */ - String LOGIC_DELETE_VALUE = "1"; + public static final String LOGIC_DELETE_VALUE = "1"; /** 逻辑不删除值 */ - String LOGIC_NOT_DELETE_VALUE = "0"; + public static final String LOGIC_NOT_DELETE_VALUE = "0"; /** ID */ - String FIELD_ID = "id"; + public static final String FIELD_ID = "id"; /** PID */ - String FIELD_PARENT_ID = "parentId"; + public static final String FIELD_PARENT_ID = "parentId"; /** PIDs */ - String FIELD_PARENT_IDS = "parentIds"; + public static final String FIELD_PARENT_IDS = "parentIds"; /** 创建人 */ - String FIELD_CREATE_BY = "createBy"; + public static final String FIELD_CREATE_BY = "createBy"; /** 更新时间 */ - String FIELD_CREATE_TIME = "createTime"; + public static final String FIELD_CREATE_TIME = "createTime"; /** 更新人 */ - String FIELD_UPDATE_BY = "updateBy"; + public static final String FIELD_UPDATE_BY = "updateBy"; /** 更新时间 */ - String FIELD_UPDATE_TIME = "updateTime"; + public static final String FIELD_UPDATE_TIME = "updateTime"; /** 逻辑删除 */ - String FIELD_DELETE_LOGIC = "deleted"; + public static final String FIELD_DELETE_LOGIC = "deleted"; /** 乐观锁 */ - String FIELD_OPTIMISTIC_LOCK = "version"; + public static final String FIELD_OPTIMISTIC_LOCK = "version"; /** 多租户字段 */ - String FIELD_TENANT = "tenantId"; + public static final String FIELD_TENANT = "tenantId"; /** 组织字段 */ - String FIELD_ORG_GROUP = "orgIds"; + public static final String FIELD_ORG_GROUP = "orgIds"; + + private MyBatisConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/OrderConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/OrderConstants.java index dff09a53aaeba61098dc5acd3afcfdf43fca926e..c5fdf7f59717afa89e5f5d55edfe3346461d90de 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/OrderConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/OrderConstants.java @@ -21,36 +21,38 @@ package org.opsli.common.constants; * @author Parker * @date 2020-09-16 17:42 */ -public interface OrderConstants { +public final class OrderConstants { /** Util 加载顺序 */ - int UTIL_ORDER = 140; + public static final int UTIL_ORDER = 140; /** 限流器 */ - int LIMITER_AOP_SORT = 149; + public static final int LIMITER_AOP_SORT = 149; /** token */ - int TOKEN_AOP_SORT = 150; + public static final int TOKEN_AOP_SORT = 150; /** 请求加解密 */ - int ENCRYPT_ADN_DECRYPT_AOP_SORT = 160; + public static final int ENCRYPT_ADN_DECRYPT_AOP_SORT = 160; /** 热点数据加载顺序 */ - int HOT_DATA_ORDER = 180; + public static final int HOT_DATA_ORDER = 180; /** 参数非法验证顺序 */ - int VERIFY_ARGS_AOP_SORT = 185; + public static final int VERIFY_ARGS_AOP_SORT = 185; /** 搜索历史 */ - int SEARCH_HIS_AOP_SORT = 186; + public static final int SEARCH_HIS_AOP_SORT = 186; /** SQL 切面执行顺序 */ - int SQL_ORDER = 190; + public static final int SQL_ORDER = 190; /** 参数非法验证顺序 */ - int LOG_ORDER = 200; + public static final int LOG_ORDER = 200; /** Controller异常拦截顺序 */ - int EXCEPTION_HANDLER_ORDER = 260; + public static final int EXCEPTION_HANDLER_ORDER = 260; + + private OrderConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..c12aef29e2e0ce44931c558393b3404db355fa32 --- /dev/null +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java @@ -0,0 +1,68 @@ +package org.opsli.common.constants; + +/** + * Redis 常量 + * {} 为项目名称 + * @author 周鹏程 + * @date 2021/12/10 19:52 + */ +public final class RedisConstants { + + + /** 字典名称 */ + public static final String PREFIX_DICT_NAME = "hash#{}:dict:name:"; + + /** 字典值 VALUE */ + public static final String PREFIX_DICT_VALUE = "hash#{}:dict:value:"; + + /** 菜单编号 */ + public static final String PREFIX_MENU_CODE = "kv#{}:menu:code:"; + + /** 参数编号 */ + public static final String PREFIX_OPTIONS_CODE = "hash#{}:options"; + + /** 用户搜索记录 */ + public static final String PREFIX_HIS_USERNAME = "zset#{}:his:username:"; + + + + /** 用户ID */ + public static final String PREFIX_USER_ID = "kv#{}:user_id:"; + + /** 用户ID 和 角色 */ + public static final String PREFIX_USER_ID_AND_ROLES = "kv#{}:user_id:roles:"; + + /** 用户ID 和 默认角色 */ + public static final String PREFIX_USER_ID_DEF_ROLE = "kv#{}:user_id:def_role_id:"; + + /** 用户ID 和 组织 */ + public static final String PREFIX_USER_ID_ORGS = "kv#{}:user_id:orgs:"; + + /** 用户ID 和 默认组织 */ + public static final String PREFIX_USER_ID_DEF_ORG = "kv#{}:user_id:def_org:"; + + /** 用户ID 和 权限 */ + public static final String PREFIX_USER_ID_PERMISSIONS = "kv#{}:user_id:permissions:"; + + /** 用户ID 和 菜单 */ + public static final String PREFIX_USER_ID_MENUS = "kv#{}:user_id:menus:"; + + /** 用户名 */ + public static final String PREFIX_USERNAME = "kv#{}:username:"; + + + + /** 票据 */ + public static final String PREFIX_TICKET = "set#{}:ticket:"; + + /** 账号失败次数 */ + public static final String PREFIX_ACCOUNT_SLIP_COUNT = "kv#{}:account:slip:count:"; + + /** 账号失败锁定KEY */ + public static final String PREFIX_ACCOUNT_SLIP_LOCK = "kv#{}:account:slip:lock:"; + + + + + private RedisConstants(){} +} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/SignConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/SignConstants.java index 31a287352651055dd5669eb5edbfb45d17ae813a..771988823e48f68d543b207deb77523775b7a2e5 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/SignConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/SignConstants.java @@ -6,24 +6,26 @@ package org.opsli.common.constants; * @author Parker * @date 2020-09-16 17:42 */ -public interface SignConstants { +public final class SignConstants { /** 用户账号 */ - String ACCOUNT = "account"; + public static final String ACCOUNT = "account"; /** 用户ID */ - String USER_ID = "userId"; + public static final String USER_ID = "userId"; /** 租户ID */ - String TENANT_ID = "tenantId"; + public static final String TENANT_ID = "tenantId"; /** 时间戳 */ - String TIMESTAMP = "timestamp"; + public static final String TIMESTAMP = "timestamp"; /** 其他信息 */ - String OTHER = "other"; + public static final String OTHER = "other"; /** 签名 类型 */ - String TYPE = "type"; + public static final String TYPE = "type"; + + private SignConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenConstants.java index d8350ce2d753e886e8ebad23ed24e91cecb481bd..803d85b7ab0eb05bd59fe34f372d2160e1781a67 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenConstants.java @@ -21,9 +21,11 @@ package org.opsli.common.constants; * @author Parker * @date 2020-09-16 17:42 */ -public interface TokenConstants { +public final class TokenConstants { /** ACCESS_TOKEN */ - String ACCESS_TOKEN = "X-Token"; + public static final String ACCESS_TOKEN = "X-Token"; + + private TokenConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenTypeConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenTypeConstants.java index cbdc34cefc4ad190006b2ba22ceec23e7b3ddbfc..998081649010ed4eca5b262ca02e55007b70500c 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenTypeConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TokenTypeConstants.java @@ -6,12 +6,13 @@ package org.opsli.common.constants; * @author Parker * @date 2020-09-16 17:42 */ -public interface TokenTypeConstants { +public final class TokenTypeConstants { /** 系统内部TOKEN */ - String TYPE_SYSTEM = "system"; + public static final String TYPE_SYSTEM = "system"; /** 外部TOKEN */ - String TYPE_EXTERNAL = "external"; + public static final String TYPE_EXTERNAL = "external"; + private TokenTypeConstants(){} } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java index ed7ec737214fb7b270d59812d5fb2b9c93ecdb0d..ce0360d1060d6294f3b56fd3f0c5cbeb0b157ca3 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java @@ -21,13 +21,15 @@ package org.opsli.common.constants; * @author Parker * @date 2021年3月10日15:50:16 */ -public interface TreeConstants { +public final class TreeConstants { /** 是否包含子集 */ - String HAS_CHILDREN = "hasChildren"; + public static final String HAS_CHILDREN = "hasChildren"; /** 是否是叶子节点 */ - String IS_LEAF = "isLeaf"; + public static final String IS_LEAF = "isLeaf"; + + private TreeConstants(){} } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/RedisMessageListenerConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/RedisMessageListenerConfig.java deleted file mode 100644 index 4f8d709a16923cf068df2cf541f7a535708c8d4b..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/RedisMessageListenerConfig.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.autoconfigure.conf; - -import lombok.extern.slf4j.Slf4j; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.listener.PatternTopic; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; -import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; - - -/** - * 消息订阅 配置 - * - * @author Parker - * @date 2020-09-15 - **/ -@Slf4j -@Configuration -@ConditionalOnProperty(name = "spring.redis.pushsub.enable", havingValue = "true") -public class RedisMessageListenerConfig { - - - /** - * redis消息监听器容器 - * 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器 - * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理 - */ - @Bean - public RedisMessageListenerContainer container(LettuceConnectionFactory lettuceConnectionFactory) { - RedisPushSubReceiver receiver = new RedisPushSubReceiver(); - RedisMessageListenerContainer container = new RedisMessageListenerContainer(); - container.setConnectionFactory(lettuceConnectionFactory); - - //订阅了的通道 - container.addMessageListener(listenerAdapter(new RedisPushSubReceiver()), new PatternTopic(receiver.getListenerChannel())); - - return container; - } - - - /** - * 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法 - * 想要处理消息 需要重写 消息接受方法 - * - */ - @Bean - public MessageListenerAdapter listenerAdapter(RedisPushSubReceiver baseReceiver) { - //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage” - //也有好几个重载方法,这边默认调用处理器的方法 叫handleMessage 可以自己到源码里面看 - //receiveMessage就是对应消费者那边的消费方法吗,而Receiver是自己弄的一个消费者类 - return new MessageListenerAdapter(baseReceiver, "receiveMessage"); - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java index e9b28b085635513298f9214b726c3912ca1029db..38ea565118d97c238461622014676a6eb1784a5d 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java @@ -32,7 +32,7 @@ import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = false) public class CacheProperties { - public static final String PROP_PREFIX = "spring.cache-conf"; + public static final String PROP_PREFIX = "spring.cache"; /** 缓存前缀 */ private String prefix; diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java index e25d33a0a177f0e8a2bda365d2aefcec6b7261b1..3f3f547e6dfad4fb1eba3ad8997e6acdb22d7519 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java @@ -37,30 +37,24 @@ import org.opsli.api.base.warpper.ApiWrapper; import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.annotation.hotdata.EnableHotData; -import org.opsli.common.constants.CacheConstants; import org.opsli.common.constants.TreeConstants; import org.opsli.common.enums.ExcelOperate; import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.TokenException; -import org.opsli.common.msg.CommonMsg; import org.opsli.common.utils.OutputStreamUtil; import org.opsli.common.utils.WrapperUtil; import org.opsli.core.autoconfigure.properties.GlobalProperties; import org.opsli.core.base.entity.BaseEntity; import org.opsli.core.base.entity.HasChildren; import org.opsli.core.base.service.interfaces.CrudServiceInterface; -import org.opsli.core.cache.local.CacheUtil; import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.TokenMsg; import org.opsli.core.security.shiro.realm.JwtRealm; -import org.opsli.core.utils.DistributedLockUtil; import org.opsli.core.utils.ExcelUtil; import org.opsli.core.utils.UserUtil; import org.opsli.plugins.excel.exception.ExcelPluginException; import org.opsli.plugins.excel.listener.BatchExcelListener; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -98,90 +92,6 @@ public abstract class BaseRestController + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.opsli.core.cache; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.util.concurrent.Striped; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.function.Function; + +/** + * 安全缓存类 + * 为了提高 缓存查询效率,放弃之前采用的分布式锁 + * 本地锁要优于分布式锁的速度,当然在秒杀系统还是要使用分布式锁的 + * + * 目前只支持 Redis 的 String 和 Hash + * + * @author Parker + * @date 2021/12/10 12:39 + */ +@Slf4j +public final class SecurityCache { + + /** 热点数据缓存时间 秒 (6小时)*/ + private static final int TTL_HOT_DATA_TIME = 21600; + /** 默认缓存时效 超出后自动清理 (分钟) */ + private static final int DEFAULT_CACHE_TIME = 5; + /** 创建缓存对象 用于存储 空缓存 */ + private static final Cache LFU_NULL_CACHE; + /** 缓存前缀 KV */ + private static final String CACHE_PREFIX_KV = "kv#"; + /** 缓存前缀 HASH */ + private static final String CACHE_PREFIX_HASH = "hash#"; + + /** 默认锁时间 (秒) */ + private static final int DEFAULT_LOCK_TIME = 10; + /** 锁 */ + @SuppressWarnings("UnstableApiUsage") + private static final Striped STRIPED = Striped.lock(1024); + + + static { + // 超时自动清理 + LFU_NULL_CACHE = CacheBuilder + .newBuilder() + .expireAfterWrite(DEFAULT_CACHE_TIME, TimeUnit.MINUTES).build(); + } + + /** + * 获得缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param callbackSource 原数据回调 + * @return Object + */ + public static Object get( + final RedisTemplate redisTemplate, + final String key, final Function callbackSource) { + return get(redisTemplate, key, callbackSource, false); + } + /** + * 获得缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param callbackSource 原数据回调 + * @return Object + */ + public static Object get( + final RedisTemplate redisTemplate, + final String key, final Function callbackSource, final boolean isEden){ + if(null == redisTemplate || null == key || null == callbackSource){ + throw new RuntimeException("入参[redisTemplate,key,callbackSource]必填"); + } + + // 缓存 Object 对象 + Object cache = getCacheObject(redisTemplate, key); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果还没查到缓存 则需要 穿透到 源数据查询 + // 开启本地锁 + @SuppressWarnings("UnstableApiUsage") + Lock lock = STRIPED.get(key); + try { + // 尝试获得锁 + if(lock.tryLock(DEFAULT_LOCK_TIME, TimeUnit.SECONDS)){ + // 梅开二度 如果查到后 直接返回 + cache = getCacheObject(redisTemplate, key); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果这时候还没有 则查询源数据 + cache = callbackSource.apply(key); + if(null == cache){ + // 存储缓存状态 + LFU_NULL_CACHE.put(key, CacheStatus.NOT_EXIST); + return null; + } + + // 存入 Redis缓存 + put(redisTemplate, key, cache, isEden); + } + }catch (Exception e){ + log.error(e.getMessage(), e); + }finally { + lock.unlock(); + } + return cache; + } + + /** + * 存储缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param val 值 + */ + public static void put( + final RedisTemplate redisTemplate, + final String key, final Object val) { + put(redisTemplate, key, val, false); + } + /** + * 存储缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param val 值 + * @param isEden 是否永久存储 + */ + public static void put( + final RedisTemplate redisTemplate, + final String key, final Object val, final boolean isEden) { + if (null == redisTemplate || null == key || null == val) { + throw new RuntimeException("入参[redisTemplate,key,val]必填"); + } + + String cacheKey = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV); + + // 判断是否为永久存储 + if(isEden) { + redisTemplate.opsForValue() + .set(cacheKey, val); + }else{ + // 随机缓存失效时间 防止缓存雪崩 + // 范围在当前时效的 1.2 - 2倍 + + // 生成随机失效时间 + int timeout = RandomUtil.randomInt( + Convert.toInt(TTL_HOT_DATA_TIME * 1.2), + Convert.toInt(TTL_HOT_DATA_TIME * 2) + ); + + redisTemplate.opsForValue() + .set( + cacheKey, + val, + timeout, + TimeUnit.SECONDS + ); + } + + // 清除本地记录 + LFU_NULL_CACHE.invalidate(key); + } + + + + /** + * 获得缓存 Hash + * @param redisTemplate redisTemplate + * @param key 主键 + * @param callbackSource 原数据回调 + * @return Object + */ + public static Object hGet( + final RedisTemplate redisTemplate, + final String key, final String field, final Function callbackSource){ + if(null == redisTemplate || null == key + || null == field || null == callbackSource){ + throw new RuntimeException("入参[redisTemplate,key,field,callbackSource]必填"); + } + + final String tempKey = key + "_" + field; + + // 缓存 Object 对象 + Object cache = getHashCacheObject(redisTemplate, key, field); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果还没查到缓存 则需要 穿透到 源数据查询 + // 开启本地锁 + @SuppressWarnings("UnstableApiUsage") + Lock lock = STRIPED.get(tempKey); + try { + // 尝试获得锁 + if(lock.tryLock(DEFAULT_LOCK_TIME, TimeUnit.SECONDS)){ + // 梅开二度 如果查到后 直接返回 + cache = getHashCacheObject(redisTemplate, key, field); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果这时候还没有 则查询源数据 + cache = callbackSource.apply(null); + if(null == cache){ + // 存储缓存状态 + LFU_NULL_CACHE.put(tempKey, CacheStatus.NOT_EXIST); + return null; + } + + // 存入 Redis缓存 + hPut(redisTemplate, key, field, cache); + } + }catch (Exception e){ + log.error(e.getMessage(), e); + }finally { + lock.unlock(); + } + return cache; + } + + /** + * 获得全部缓存 Hash + * 注:没有补偿机制 如果当前hash缓存 不是通过程序被删除 + * 直接从redis 中将缓存干掉,人为的造成 redis与数据库缓存不一致则没救 + * + * @param redisTemplate redisTemplate + * @param key 主键 + * @param callbackSource 原数据回调 + * @return Object + */ + public static Map hGetAll( + final RedisTemplate redisTemplate, final String key, + final Function> callbackSource){ + if(null == redisTemplate || null == key + || null == callbackSource){ + throw new RuntimeException("入参[redisTemplate,key,callbackSource]必填"); + } + + // 缓存 Object 对象 + Map cache = getAllHashCacheObject(redisTemplate, key, null); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果还没查到缓存 则需要 穿透到 源数据查询 + // 开启本地锁 + @SuppressWarnings("UnstableApiUsage") + Lock lock = STRIPED.get(key); + try { + // 尝试获得锁 + if(lock.tryLock(DEFAULT_LOCK_TIME, TimeUnit.SECONDS)){ + // 梅开二度 如果查到后 直接返回 + cache = getAllHashCacheObject(redisTemplate, key, null); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果这时候还没有 则查询源数据 + cache = callbackSource.apply(null); + if(null == cache){ + // 存储缓存状态 + LFU_NULL_CACHE.put(key, CacheStatus.NOT_EXIST); + return null; + } + + // 存入 Redis缓存 + hAllPut(redisTemplate, key, cache); + } + }catch (Exception e){ + log.error(e.getMessage(), e); + }finally { + lock.unlock(); + } + return cache; + } + + + /** + * 获得全部缓存 Hash + * + * @param redisTemplate redisTemplate + * @param key 主键 + * @param callbackSourceCount 原数据数量回调 + * @param callbackSource 原数据回调 + * @return Object + */ + public static Map hGetAll( + final RedisTemplate redisTemplate, final String key, + final Function callbackSourceCount, final Function> callbackSource){ + if(null == redisTemplate || null == key + || null == callbackSourceCount || null == callbackSource){ + throw new RuntimeException("入参[redisTemplate,key,callbackSourceCount,callbackSource]必填"); + } + + // 缓存 Object 对象 + Map cache = getAllHashCacheObject(redisTemplate, key, callbackSourceCount); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果还没查到缓存 则需要 穿透到 源数据查询 + // 开启本地锁 + @SuppressWarnings("UnstableApiUsage") + Lock lock = STRIPED.get(key); + try { + // 尝试获得锁 + if(lock.tryLock(DEFAULT_LOCK_TIME, TimeUnit.SECONDS)){ + // 梅开二度 如果查到后 直接返回 + cache = getAllHashCacheObject(redisTemplate, key, callbackSourceCount); + // 如果缓存不为空 则直接返回 + if(null != cache){ + return cache; + } + + // 如果这时候还没有 则查询源数据 + cache = callbackSource.apply(null); + if(null == cache){ + // 存储缓存状态 + LFU_NULL_CACHE.put(key, CacheStatus.NOT_EXIST); + return null; + } + + // 存入 Redis缓存 + hAllPut(redisTemplate, key, cache); + } + }catch (Exception e){ + log.error(e.getMessage(), e); + }finally { + lock.unlock(); + } + return cache; + } + + + /** + * Hash 存储缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param cacheMap 缓存Map + */ + public static void hAllPut( + final RedisTemplate redisTemplate, + final String key, final Map cacheMap) { + if (null == redisTemplate || null == key + || null == cacheMap) { + throw new RuntimeException("入参[redisTemplate,key,cacheMap]必填"); + } + + String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH); + + redisTemplate.opsForHash() + .putAll(cacheKeyByHash, cacheMap); + + // 清除本地记录 + LFU_NULL_CACHE.invalidate(key); + } + + /** + * Hash 存储缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param field 字段 + * @param val 值 + */ + public static void hPut( + final RedisTemplate redisTemplate, + final String key, final String field, final Object val) { + if (null == redisTemplate || null == key + || null == field || null == val) { + throw new RuntimeException("入参[redisTemplate,key,field,val]必填"); + } + + String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH); + + redisTemplate.opsForHash() + .put(cacheKeyByHash, field, val); + + final String tempKey = key + "_" + field; + // 清除本地记录 + LFU_NULL_CACHE.invalidate(tempKey); + } + + + /** + * 批量删除 Hash缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param fields 字段 + * @return boolean + */ + public static boolean hDelMore( + final RedisTemplate redisTemplate, + final String key, final String... fields) { + if (null == redisTemplate || null == key + || null == fields ) { + throw new RuntimeException("入参[redisTemplate,key,fields]必填"); + } + + int count = fields.length; + for (String field : fields) { + boolean isDel = hDel(redisTemplate, key, field); + if(isDel){ + count--; + } + } + return 0 == count; + } + + /** + * 删除 Hash缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + * @param field 字段 + * @return boolean + */ + public static boolean hDel( + final RedisTemplate redisTemplate, + final String key, final String field) { + if (null == redisTemplate || null == key + || null == field ) { + throw new RuntimeException("入参[redisTemplate,key,field]必填"); + } + + final String tempKey = key + "_" + field; + + // 清除本地记录 + LFU_NULL_CACHE.invalidate(tempKey); + + // 判断是否存在 + boolean isExist = Boolean.TRUE.equals(redisTemplate.opsForHash().hasKey(key, field)); + if(!isExist){ + // 如果不存在 直接返回删除成功 + return true; + } + + // 清除缓存 + return 0 != redisTemplate.opsForHash().delete(key, field); + } + + + /** + * 批量删除缓存 + * @param redisTemplate redisTemplate + * @param keys 主键 + */ + public static boolean removeMore( + final RedisTemplate redisTemplate, + final String... keys) { + if (null == redisTemplate || null == keys) { + throw new RuntimeException("入参[redisTemplate,keys]必填"); + } + + int count = keys.length; + for (String key : keys) { + boolean isRemove = remove(redisTemplate, key); + if(isRemove){ + count--; + } + } + return 0 == count; + } + + /** + * 删除缓存 + * @param redisTemplate redisTemplate + * @param key 主键 + */ + public static boolean remove( + final RedisTemplate redisTemplate, + final String key) { + if (null == redisTemplate || null == key) { + throw new RuntimeException("入参[redisTemplate,key]必填"); + } + + // 清除本地记录 + LFU_NULL_CACHE.invalidate(key); + + String cacheKeyByKv = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV); + String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH); + + // 清除缓存 + redisTemplate.delete(cacheKeyByKv); + redisTemplate.delete(cacheKeyByHash); + return true; + } + + + // ================================================================================================================= + + /** + * 从Redis 直接获得缓存 + * @param redisTemplate redisTemplate + * @param key Key + * @return Object + */ + private static Object getCacheObject(RedisTemplate redisTemplate, String key) { + Object cache = null; + try { + // 先判断本地缓存是否存在 默认为存在(类似于伪布隆过滤) + CacheStatus cacheStatus = LFU_NULL_CACHE.get(key, () -> CacheStatus.EXIST); + // 如果不存在 则直接返回空 + if(CacheStatus.NOT_EXIST.equals(cacheStatus)){ + return null; + } + + String cacheKey = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV); + + // 从 缓存回调查询数据 + cache = redisTemplate.opsForValue().get(cacheKey); + }catch (Exception e){ + log.error(e.getMessage(), e); + } + return cache; + } + + /** + * 从Redis 直接获得缓存 Hash + * @param redisTemplate redisTemplate + * @param key Key + * @return Object + */ + private static Object getHashCacheObject(RedisTemplate redisTemplate, String key, String field) { + Object cache = null; + try { + final String tempKey = key + "_" + field; + + // 先判断本地缓存是否存在 默认为存在(类似于伪布隆过滤) + CacheStatus cacheStatus = LFU_NULL_CACHE.get(tempKey, () -> CacheStatus.EXIST); + // 如果不存在 则直接返回空 + if(CacheStatus.NOT_EXIST.equals(cacheStatus)){ + return null; + } + + String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH); + + // 从 缓存回调查询数据 + cache = redisTemplate.opsForHash().get(cacheKeyByHash, field); + }catch (Exception e){ + log.error(e.getMessage(), e); + } + return cache; + } + + + /** + * 从Redis 直接获得全部缓存 Hash + * @param redisTemplate redisTemplate + * @param key key + * @param callbackSourceCount callbackSourceCount + * @return Object + */ + private static Map getAllHashCacheObject(RedisTemplate redisTemplate, String key, + final Function callbackSourceCount) { + Map cache = null; + try { + // 先判断本地缓存是否存在 默认为存在(类似于伪布隆过滤) + CacheStatus cacheStatus = LFU_NULL_CACHE.get(key, () -> CacheStatus.EXIST); + // 如果不存在 则直接返回空 + if(CacheStatus.NOT_EXIST.equals(cacheStatus)){ + return null; + } + + String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH); + + // 从 缓存回调查询数据 + Map entries = redisTemplate.opsForHash().entries(cacheKeyByHash); + + // 如果补偿器不为空 则进行补偿判断 + if(null != callbackSourceCount){ + // 判断数量不相等 则返回一个空 重新查询处理缓存 + Integer count = callbackSourceCount.apply(key); + if(count != entries.size()){ + return null; + } + } + + if(MapUtil.isNotEmpty(entries)){ + cache = new HashMap<>(); + for (Map.Entry entry : entries.entrySet()) { + cache.put(String.valueOf(entry.getKey()), entry.getValue()); + } + } + }catch (Exception e){ + log.error(e.getMessage(), e); + } + return cache; + } + + /** + * 状态 + */ + private enum CacheStatus{ + + /** 存在(默认) */ + EXIST, + + /** 不存在 */ + NOT_EXIST + + } + + /** + * 私有化构造函数 + */ + private SecurityCache(){} + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java deleted file mode 100644 index a9d80d8c749370aadd0b38759c3513d005a78a16..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java +++ /dev/null @@ -1,813 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.local; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.core.util.XmlUtil; -import com.alibaba.fastjson.JSONObject; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import lombok.extern.slf4j.Slf4j; -import org.opsli.common.constants.CacheConstants; -import org.opsli.common.enums.CacheType; -import org.opsli.core.autoconfigure.properties.CacheProperties; -import org.opsli.core.msg.CoreMsg; -import org.opsli.core.utils.ThrowExceptionUtil; -import org.opsli.plugins.cache.EhCachePlugin; -import org.opsli.plugins.redis.RedisPlugin; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.annotation.Order; -import org.springframework.core.io.ClassPathResource; -import org.springframework.stereotype.Component; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; - -/** - * 缓存工具类 - * - * 一、控制key的生命周期,Redis不是垃圾桶(缓存不是垃圾桶) - * 建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime。 - * - * 二、【强制】:拒绝bigkey(防止网卡流量、慢查询) - * string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。 - * - * @author Parker - * @date 2020-09-16 16:20 - */ -@Slf4j -@Order(UTIL_ORDER) -@Component -public class CacheUtil { - - /** 热点数据缓存时间 秒 (6小时)*/ - private static int TTL_HOT_DATA_TIME = 21600; - /** 空缓存时间 秒 */ - private final static int TTL_NIL_DATA_TIME = 300; - /** Redis插件 */ - private static RedisPlugin redisPlugin; - /** EhCache插件 */ - private static EhCachePlugin ehCachePlugin; - /** Json key */ - public static final String JSON_KEY = "data"; - /** 空状态 key 前缀 */ - private static final String NIL_FLAG_PREFIX = "nil"; - /** 空状态 生效阈值 */ - private final static long NIL_FLAG_THRESHOLD = 3; - - /** 热点数据前缀 */ - private static String PREFIX_NAME; - - /** 增加初始状态开关 防止异常使用 */ - private static boolean IS_INIT; - - static { - try { - // 读取配置信息 - CacheUtil.readPropertyXML(); - }catch (Exception ignored){} - } - - /*** - * 获得缓存前缀 - * @return String - */ - public static String getPrefixName() { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - return PREFIX_NAME; - } - - // ========================= GET ========================= - - /** - * 获得 普通 缓存 - * @param key 键 - * @return Object - */ - public static Object getTimed(final String key){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(key, false, false); - } - - /** - * 获得 普通 缓存 - * @param key 键 - * @param isSaveLocal 是否保存到本地 - * @return Object - */ - public static Object getTimed(final String key, final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(key, false, isSaveLocal); - } - - /** - * 获得 普通 缓存 - * @param vClass 泛型Class - * @param key 键 - * @return 泛型 - */ - public static V getTimed(final Class vClass, final String key){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(vClass, key, false, false); - } - - /** - * 获得 普通 缓存 - * @param vClass 泛型Class - * @param key 键 - * @param isSaveLocal 是否保存到本地 - * @return 泛型 - */ - public static V getTimed(final Class vClass, final String key, - final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(vClass, key, false, isSaveLocal); - } - - /** - * 获得 普通 缓存 - * @param key 键 - * @return Object - */ - public static Object getEden(final String key){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(key, true, false); - } - - /** - * 获得 普通 缓存 - * @param key 键 - * @param isSaveLocal 是否保存到本地 - * @return Object - */ - public static Object getEden(final String key, final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(key, true, isSaveLocal); - } - - /** - * 获得 普通 缓存 - * @param vClass 泛型Class - * @param key 键 - * @return 泛型 - */ - public static V getEden(final String key, final Class vClass){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(vClass, key, true, false); - } - - /** - * 获得 普通 缓存 - * @param vClass 泛型Class - * @param key 键 - * @param isSaveLocal 是否保存到本地 - * @return 泛型 - */ - public static V getEden(final String key, final boolean isSaveLocal, - final Class vClass){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 转换数据泛型 - return CacheUtil.get(vClass, key, true, isSaveLocal); - } - - /** - * 获得 普通 缓存 - * @param vClass 泛型Class - * @param key 键 - * @param isEden 是否永久层数据 - * @param isSaveLocal 是否保存到本地 - * @return 泛型 - */ - private static V get(final Class vClass, final String key, final boolean isEden, - final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 获得缓存数据 - Object cacheObj = CacheUtil.get(key, isEden, isSaveLocal); - // 转换数据泛型 - return Convert.convert(vClass, cacheObj); - } - - /** - * 获得 普通 缓存 - * @param key 键 - * @param isEden 是否永久层数据 - * @param isSaveLocal 是否保存到本地 - * @return Object - */ - private static Object get(final String key, final boolean isEden, final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 缓存 Key - String cacheKey = CacheUtil.handleUsualKey(key, isEden); - - // 获得缓存Json - JSONObject cacheJson; - - // 判读是否需要 先从本地缓存获取 - if(isSaveLocal){ - // 获得缓存Json - cacheJson = ehCachePlugin.get(CacheConstants.EHCACHE_SPACE, - cacheKey, JSONObject.class); - if(cacheJson != null){ - return cacheJson.get(JSON_KEY); - } - } - - // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存 - cacheJson = (JSONObject) redisPlugin.get(cacheKey); - if(cacheJson != null){ - // 判读是否需要 存入本地EhCache - if(isSaveLocal){ - //存入EhCache - ehCachePlugin.put(CacheConstants.EHCACHE_SPACE, - cacheKey, cacheJson); - } - } - - return cacheJson != null ? cacheJson.get(JSON_KEY) : null; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return null; - } - - - - /** - * 获得 Hash 缓存 - * @param vClass 泛型Class - * @param key 键 - * @param field 字段名 - * @return 泛型 - */ - public static V getHash(final Class vClass, final String key, final String field){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 获得缓存数据 - Object cacheObj = CacheUtil.getHash(key, field, false); - // 转换数据泛型 - return Convert.convert(vClass, cacheObj); - } - - /** - * 获得 Hash 缓存 - * @param key 键 - * @param field 字段名 - * @param isSaveLocal 是否保存到本地 - * @param vClass 泛型Class - * @return 泛型 - */ - public static V getHash(final Class vClass, final String key, - final String field, final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 获得缓存数据 - Object cacheObj = CacheUtil.getHash(key, field, isSaveLocal); - // 转换数据泛型 - return Convert.convert(vClass, cacheObj); - } - - /** - * 获得 Hash 缓存 - * @param key 键 - * @param field 字段名 - * @return Object - */ - public static Object getHash(final String key, final String field){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - return CacheUtil.getHash(key, field, false); - } - - /** - * 获得 Hash 缓存 - * @param key 键 - * @param field 字段名 - * @param isSaveLocal 是否保存到本地 - * @return Object - */ - public static Object getHash(final String key, final String field, - final boolean isSaveLocal){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 缓存 Key - String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key); - - // 获得缓存Json - JSONObject cacheJson; - - // 判读是否需要 先从本地缓存获取 - if(isSaveLocal){ - // 获得缓存Json - cacheJson = ehCachePlugin.get(CacheConstants.EHCACHE_SPACE, - cacheKey +":"+ field, JSONObject.class); - if(cacheJson != null){ - return cacheJson.get(JSON_KEY); - } - } - - // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存 - cacheJson = (JSONObject) redisPlugin.hGet(cacheKey, field); - if(cacheJson != null){ - // 判读是否需要 存入本地EhCache - if(isSaveLocal){ - //存入EhCache - ehCachePlugin.put(CacheConstants.EHCACHE_SPACE, - cacheKey + ":" + field, cacheJson); - } - } - - return cacheJson != null ? cacheJson.get(JSON_KEY) : null; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return null; - } - - - /** - * 获得 Hash 缓存 - * @param key 键 - * @return Object - */ - public static Map getHashAll(final String key){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 缓存 Key - String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key); - - Map retMap = Maps.newHashMap(); - - // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存 - Map allCache = redisPlugin.hGetAll(cacheKey); - if(CollUtil.isEmpty(allCache)){ - return retMap; - } - - for (Map.Entry entry : allCache.entrySet()) { - // 赋值 - JSONObject jsonObject = (JSONObject) entry.getValue(); - if (jsonObject == null) { - continue; - } - Object data = jsonObject.get(CacheUtil.JSON_KEY); - if (data == null) { - continue; - } - - retMap.put(Convert.toStr(entry.getKey()), data); - } - - return retMap; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return null; - } - - // ========================= PUT ========================= - - - /** - * 存普通缓存 - * @param key 键 - * @param value 值 - * @return boolean - */ - public static boolean put(final String key, final Object value) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - return CacheUtil.put(key, value, false); - } - - /** - * 存永久缓存 - * @param key 键 - * @param value 值 - * @param isEden 是否永久存储 - * @return boolean - */ - public static boolean put(final String key, final Object value, final boolean isEden) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 自动处理 key - - // 则统一转换为 JSONObject - JSONObject cacheJson = new JSONObject(); - cacheJson.put(JSON_KEY, value); - - // 缓存 Key - String cacheKey = CacheUtil.handleUsualKey(key, isEden); - - // 判断是否为永久存储 - if(isEden) { - // 存入Redis - return redisPlugin.put(cacheKey, cacheJson); - }else{ - // 随机缓存失效时间 防止缓存雪崩 - // 范围在当前时效的 1.2 - 2倍 - - // 生成随机失效时间 - int timeout = RandomUtil.randomInt( - Convert.toInt(TTL_HOT_DATA_TIME * 1.2), - Convert.toInt(TTL_HOT_DATA_TIME * 2) - ); - - // 存入Redis - return redisPlugin.put(cacheKey, cacheJson, timeout); - } - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - - - /** - * 存 永久 Hash 缓存 - * @param key 键 - * @param field 字段名 - * @param value 值 - * @return boolean - */ - public static boolean putHash(final String key, final String field, final Object value) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 处理 key - String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key); - - // 则统一转换为 JSONObject - JSONObject cacheJson = new JSONObject(); - cacheJson.put(JSON_KEY, value); - - // 存入Redis - return redisPlugin.hPut(cacheKey, field, cacheJson); - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - - // ========================= DEL ========================= - - - /** - * 删缓存 - * @param key 键 - * @return boolean - */ - public static boolean del(final String key) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 计数器 - int count = 0; - - Object timed = CacheUtil.getTimed(key); - Object eden = CacheUtil.getEden(key); - - // 删除key 集合 - List cacheKeys = Lists.newArrayList(); - if(timed != null){ - count+=2; - // 处理 key - 时控数据 - cacheKeys.add( - CacheUtil.handleKey(CacheType.TIMED, key) - ); - } - if(eden != null){ - count+=2; - // 处理 key - 永久数据 - cacheKeys.add( - CacheUtil.handleKey(CacheType.EDEN, key)); - } - - // 循环删除缓存数据 - for (String cacheKey : cacheKeys) { - - // 删除 EhCache - boolean ehcacheRet = ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey); - if(ehcacheRet){ - count--; - } - - // 删除 Redis - boolean redisRet = redisPlugin.del(cacheKey); - if(redisRet){ - count--; - } - } - - return count == 0; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - /** - * 删 Hash 缓存 - * @param key 键 - * @param field 字段名 - * @return boolean - */ - public static boolean delHash(final String key, final String field) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - // 计数器 - int count = 2; - - // 自动处理 key - String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key); - - // 删除 EhCache - boolean ehcacheRet = ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE,cacheKey +":"+ field); - if(ehcacheRet){ - count--; - } - - // 删除 Redis - Long hDeleteLong = redisPlugin.hDelete(cacheKey, field); - if(hDeleteLong != null && hDeleteLong > 0){ - count--; - } - - return count == 0; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - // ==================================================================== - - /** - * 放一个空属性 有效时间为 5分钟 - * 用于 防止穿透判断 弥补布隆过滤器 - * - * @param key 键 - * @return boolean - */ - public static boolean putNilFlag(String key) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - // 处理缓存 key - String cacheKey = CacheUtil.handleKey(NIL_FLAG_PREFIX + ":" + key); - - try { - // 存入Redis - Long increment = redisPlugin.increment(cacheKey); - // 设置失效时间 - redisPlugin.expire(cacheKey, TTL_NIL_DATA_TIME); - return increment != null; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - /** - * 删除空属性 - * 用于 防止穿透判断 弥补布隆过滤器 - * - * @param key 键 - * @return boolean - */ - public static boolean delNilFlag(String key) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 处理缓存 key - String cacheKey = CacheUtil.handleKey(NIL_FLAG_PREFIX + ":" + key); - try { - // 删除Redis - return redisPlugin.del(cacheKey); - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - - /** - * 获得一个空属性 有效时间为 5分钟 - * 用于 防止穿透判断 弥补布隆过滤器 - * - * @param key 键 - * @return boolean - */ - public static boolean hasNilFlag(String key) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - // 处理缓存 key - String cacheKey = CacheUtil.handleKey(NIL_FLAG_PREFIX + ":" + key); - - try { - Object nilObj = redisPlugin.get(cacheKey); - if(nilObj == null){ - return false; - } - - Long nilNum = Convert.toLong(nilObj, 0L); - return NIL_FLAG_THRESHOLD < nilNum; - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return false; - } - - - // ==================================================================== - - /** - * 处理 key 默认为临时 - * @param key 缓存Key - * @return String - */ - public static String handleKey(String key){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - return CacheUtil.handleKey(CacheType.TIMED, key); - } - - /** - * 处理 key - * @param cacheType 缓存类型 - * @param key 缓存Key - * @return String - */ - public static String handleKey(CacheType cacheType, String key){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - return PREFIX_NAME + cacheType.getName() + ":" + - key; - } - - /** - * 内部处理 普通 key - * @param key 缓存Key - * @param isEden 是否永久 - * @return String - */ - private static String handleUsualKey(String key, boolean isEden){ - if(isEden){ - return CacheUtil.handleKey(CacheType.EDEN, key); - } - return CacheUtil.handleKey(CacheType.TIMED, key); - } - - /** - * 读配置文件 - */ - private static void readPropertyXML() throws IOException { - // 有坑 读 xml - ClassPathResource resource = new ClassPathResource("config/ehcache-opsli.xml"); - Document document = XmlUtil.readXML(resource.getInputStream()); - NodeList nodeList = document.getElementsByTagName("cache"); - if(nodeList != null){ - for (int i = 0; i < nodeList.getLength(); i++) { - Node item = nodeList.item(i); - NamedNodeMap attributes = item.getAttributes(); - if(attributes == null){ - continue; - } - Node alias = attributes.getNamedItem("alias"); - if("hotData".equals(alias.getNodeValue())){ - NodeList childNodes = item.getChildNodes(); - if(childNodes != null){ - for (int j = 0; j < childNodes.getLength(); j++) { - if("expiry".equals(childNodes.item(j).getNodeName())){ - NodeList expiryNodes = childNodes.item(j).getChildNodes(); - if(expiryNodes != null){ - for (int k = 0; k < expiryNodes.getLength(); k++) { - if("ttl".equals(expiryNodes.item(k).getNodeName())){ - Node ttlNode = expiryNodes.item(k); - Node ttlValue = ttlNode.getFirstChild(); - // 默认 60000秒 6小时 - TTL_HOT_DATA_TIME = Convert.toInt(ttlValue.getNodeValue(), 21600); - break; - } - } - } - break; - } - } - } - break; - } - } - } - } - - /** - * 初始化 - */ - @Autowired - public void init(CacheProperties cacheProperties, - RedisPlugin redisPlugin, - EhCachePlugin ehCachePlugin){ - - CacheUtil.PREFIX_NAME = Convert.toStr(cacheProperties.getPrefix(), "opsli") + ":"; - CacheUtil.redisPlugin = redisPlugin; - CacheUtil.ehCachePlugin = ehCachePlugin; - - IS_INIT = true; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/entity/CacheDataEntity.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/entity/CacheDataEntity.java deleted file mode 100644 index dc557df36b2d8059a1d094ccd42cd21028c77409..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/entity/CacheDataEntity.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.opsli.core.cache.pushsub.enums.PushSubType; - -/** - * 热点数据处理 Entity - * - * @author Parker - * @date 2020-09-18 00:01 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class CacheDataEntity { - - /** key */ - private String key; - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/CacheHandleType.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/CacheHandleType.java deleted file mode 100644 index 4ad27cf98b0b90e659931f6c978e0b688da9473c..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/CacheHandleType.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.enums; - -/** - * 缓存操作类型 - * - * @author Parker - * @date 2020-09-16 - */ -public enum CacheHandleType { - - /** 更新 */ - UPDATE, - - /** 删除 */ - DELETE, - - ; - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/DictModelType.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/DictModelType.java deleted file mode 100644 index 2ff51023e44e168d71618b1852ea1998ec26c324..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/DictModelType.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.enums; - -/** - * 缓存操作类型 - * - * @author Parker - * @date 2020-09-16 - */ -public enum DictModelType { - - /** 对象 */ - OBJECT, - - /** 集合 */ - COLLECTION, - - ; - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/MsgArgsType.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/MsgArgsType.java deleted file mode 100644 index 2c4d8667963ca83daa1e15507454e63140da9f9a..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/MsgArgsType.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.enums; - -/** - * 消息具体类型 - * - * @author Parker - * @date 2020-09-16 - */ -public enum MsgArgsType { - - /** 字典模型 */ - DICT_MODEL, - /** 字典模型-集合 */ - DICT_MODELS, - /** 字典模型-传输类型 */ - DICT_MODEL_TYPE, - /** 字典操作类型 */ - DICT_TYPE, - - /** 用户ID */ - USER_ID, - /** 用户名 */ - USER_USERNAME, - /** 用户数据类型 */ - USER_MODEL_TYPE, - /** 用户数据*/ - USER_MODEL_DATA, - - /** 组织 用户ID */ - ORG_USER_ID, - /** 组织 用户数据 */ - ORG_USER_DATA, - - /** 租户ID */ - TENANT_ID, - /** 租户数据 */ - TENANT_DATA, - - /** 参数编号 */ - OPTION_CODE, - /** 参数数据*/ - OPTION_MODEL_DATA, - - /** 缓存数据Key */ - CACHE_DATA_KEY, - /** 缓存数据Value */ - CACHE_DATA_VALUE, - /** 缓存数据Type */ - CACHE_DATA_TYPE, - ; - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/PushSubType.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/PushSubType.java deleted file mode 100644 index e1c48112760a130105b1f183908e959069f67d09..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/PushSubType.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.enums; - -/** - * 发布订阅类型 - * - * @author Parker - * @date 2020-09-16 - */ -public enum PushSubType { - - /** 字典类型 */ - DICT, - - /** 用户数据 */ - USER, - - /** 菜单数据 */ - MENU, - - /** 组织数据 */ - ORG, - - /** 租户 */ - TENANT, - - /** 系统数据 */ - OPTION, - - /** 热点数据 */ - HOT_DATA, - - ; - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/UserModelType.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/UserModelType.java deleted file mode 100644 index 08c2acde66bdcb61178effebbea451fd61285ec9..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/enums/UserModelType.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.enums; - -/** - * 用户缓存操作类型 - * - * @author Parker - * @date 2020-09-16 - */ -public enum UserModelType { - - /** 用户模型 */ - USER_MODEL, - /** 用户角色集合模型 */ - USER_ROLES_MODEL, - /** 用户权限集合模型 */ - USER_PERMS_MODEL, - /** 用户菜单集合模型 */ - USER_MENU_MODEL, - - ; - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/DictHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/DictHandler.java deleted file mode 100644 index 568e2a8536f3e3395f6e591593c4efb89830d6f3..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/DictHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.handler; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; -import com.alibaba.fastjson.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.opsli.api.wrapper.system.dict.DictWrapper; -import org.opsli.common.constants.CacheConstants; -import org.opsli.common.constants.DictConstants; -import org.opsli.common.enums.CacheType; -import org.opsli.core.cache.local.CacheUtil; -import org.opsli.core.cache.pushsub.enums.CacheHandleType; -import org.opsli.core.cache.pushsub.enums.DictModelType; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.plugins.cache.EhCachePlugin; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.List; - -/** - * 字典消息处理 - * - * @author Parker - * @date 2020-09-16 - */ -@Slf4j -public class DictHandler implements RedisPushSubHandler{ - - @Autowired - private EhCachePlugin ehCachePlugin; - - @Override - public PushSubType getType() { - return PushSubType.DICT; - } - - @Override - public void handler(JSONObject msgJson) { - DictModelType dictModelType = DictModelType.valueOf((String) msgJson.get(MsgArgsType.DICT_MODEL_TYPE.toString())); - CacheHandleType type = CacheHandleType.valueOf((String) msgJson.get(MsgArgsType.DICT_TYPE.toString())); - - if(DictModelType.COLLECTION == dictModelType){ - Object dictListObj = msgJson.get(MsgArgsType.DICT_MODELS.toString()); - List dictWrappers = Convert.toList(DictWrapper.class, dictListObj); - if(CollUtil.isNotEmpty(dictWrappers)){ - for (DictWrapper dictWrapper : dictWrappers) { - this.handler(dictWrapper, type); - } - } - } else if(DictModelType.OBJECT == dictModelType){ - JSONObject jsonObject = msgJson.getJSONObject(MsgArgsType.DICT_MODEL.toString()); - if(jsonObject == null){ - return; - } - - DictWrapper dictWrapperModel = jsonObject.toJavaObject(DictWrapper.class); - this.handler(dictWrapperModel, type); - } - } - - - /** - * 真正处理 - 只是处理自己本地的缓存 - * @param dictWrapperModel model - * @param type 类型 - */ - private void handler(DictWrapper dictWrapperModel, CacheHandleType type){ - - // 解析 key - String ehKeyByName = CacheUtil.handleKey(CacheType.EDEN_HASH, DictConstants.CACHE_PREFIX_NAME + - dictWrapperModel.getTypeCode() + ":" + dictWrapperModel.getDictName()); - String ehKeyByValue = CacheUtil.handleKey(CacheType.EDEN_HASH, DictConstants.CACHE_PREFIX_VALUE + - dictWrapperModel.getTypeCode() + ":" + dictWrapperModel.getDictValue()); - - // 缓存更新 - if(CacheHandleType.UPDATE == type){ - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, ehKeyByName); - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, ehKeyByValue); - - // 统一转换为 JSONObject - String jsonStr = JSONObject.toJSONString(dictWrapperModel.getModel()); - JSONObject value = JSONObject.parseObject(jsonStr); - ehCachePlugin.put(CacheConstants.EHCACHE_SPACE, ehKeyByName, value); - ehCachePlugin.put(CacheConstants.EHCACHE_SPACE, ehKeyByValue, value); - } - // 缓存删除 - else if(CacheHandleType.DELETE == type){ - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, ehKeyByName); - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, ehKeyByValue); - } - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/HotDataHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/HotDataHandler.java deleted file mode 100644 index 5c5a4fed43e04294332a1d6edf5b2009edf392d7..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/HotDataHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.handler; - -import com.alibaba.fastjson.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.opsli.common.constants.CacheConstants; -import org.opsli.core.cache.local.CacheUtil; -import org.opsli.core.cache.pushsub.enums.CacheHandleType; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.plugins.cache.EhCachePlugin; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * 热数据处理 - * - * @author Parker - * @date 2020-09-16 - */ -@Slf4j -public class HotDataHandler implements RedisPushSubHandler{ - - @Autowired - private EhCachePlugin ehCachePlugin; - - @Override - public PushSubType getType() { - return PushSubType.HOT_DATA; - } - - @Override - public void handler(JSONObject msgJson) { - String key = (String) msgJson.get(MsgArgsType.CACHE_DATA_KEY.toString()); - Object value = msgJson.get(MsgArgsType.CACHE_DATA_VALUE.toString()); - CacheHandleType type = CacheHandleType.valueOf((String )msgJson.get(MsgArgsType.CACHE_DATA_TYPE.toString())); - - if(StringUtils.isEmpty(key)){ - return; - } - - // 拼装缓存key - String cacheName = CacheUtil.handleKey(CacheConstants.HOT_DATA_PREFIX +":"+ key); - - if(CacheHandleType.UPDATE == type){ - ehCachePlugin.put(CacheConstants.EHCACHE_SPACE, cacheName, value); - } - // 缓存删除 - else if(CacheHandleType.DELETE == type){ - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheName); - } - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OptionHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OptionHandler.java deleted file mode 100644 index c32e2365a16e17aff47ee1ba11114f8bdfc2331d..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OptionHandler.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.handler; - -import com.alibaba.fastjson.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.opsli.common.constants.CacheConstants; -import org.opsli.core.cache.local.CacheUtil; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.utils.OptionsUtil; -import org.opsli.plugins.cache.EhCachePlugin; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * 系统参数消息处理 - * - * @author Parker - * @date 2020-09-16 - */ -@Slf4j -public class OptionHandler implements RedisPushSubHandler{ - - @Autowired - private EhCachePlugin ehCachePlugin; - - @Override - public PushSubType getType() { - return PushSubType.OPTION; - } - - @Override - public void handler(JSONObject msgJson) { - // 系统参数刷新 - this.optionHandler(msgJson); - } - - /** - * 用户数据处理 - * @param msgJson 信息Json - */ - private void optionHandler(JSONObject msgJson){ - JSONObject data = msgJson.getJSONObject(MsgArgsType.OPTION_MODEL_DATA.toString()); - // 数据为空则不执行 - if(data == null){ - return; - } - - // 获得参数编号 - String optionCode = (String) msgJson.get(MsgArgsType.OPTION_CODE.toString()); - if(StringUtils.isEmpty(optionCode)){ - return; - } - - String cacheKey = CacheUtil.handleKey(OptionsUtil.PREFIX_CODE + optionCode); - - // 先删除 - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey); - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OrgHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OrgHandler.java deleted file mode 100644 index fc98d3a97842f88e052c5483d59682e3ad1bbd63..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OrgHandler.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.handler; - -import com.alibaba.fastjson.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.opsli.common.constants.CacheConstants; -import org.opsli.core.cache.local.CacheUtil; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.utils.OrgUtil; -import org.opsli.core.utils.UserUtil; -import org.opsli.plugins.cache.EhCachePlugin; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * 用户组织消息处理 - * - * @author Parker - * @date 2020-09-16 - */ -@Slf4j -public class OrgHandler implements RedisPushSubHandler{ - - @Autowired - private EhCachePlugin ehCachePlugin; - - @Override - public PushSubType getType() { - return PushSubType.ORG; - } - - @Override - public void handler(JSONObject msgJson) { - // 用户刷新 - this.orgHandler(msgJson); - } - - /** - * 用户组织数据处理 - * @param msgJson 信息Json - */ - private void orgHandler(JSONObject msgJson){ - JSONObject data = msgJson.getJSONObject(MsgArgsType.ORG_USER_DATA.toString()); - // 数据为空则不执行 - if(data == null){ - return; - } - - // 获得用户ID - String userId = (String) msgJson.get(MsgArgsType.ORG_USER_ID.toString()); - if(StringUtils.isEmpty(userId)){ - return; - } - - String cacheKey = CacheUtil.handleKey(UserUtil.PREFIX_ID_ORGS + userId); - - // 先删除 - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey); - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/RedisPushSubHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/RedisPushSubHandler.java deleted file mode 100644 index 7645af6ae78822d2622e8abad58ddb78f19c4a1e..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/RedisPushSubHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.handler; - -import com.alibaba.fastjson.JSONObject; -import org.opsli.core.cache.pushsub.enums.PushSubType; - -/** - * 标示类 用于获得 消息未知 - * - * @author Parker - * @date 2020-09-16 - */ -public interface RedisPushSubHandler { - - /** - * 获得类型 - * @return 类型 - */ - PushSubType getType(); - - /** - * 消息处理 - * @param msgJson 信息Json - */ - void handler(JSONObject msgJson); - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/UserHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/UserHandler.java deleted file mode 100644 index 345cc7bec0d30b259e8ec3703ced81e98f333927..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/UserHandler.java +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.handler; - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.opsli.common.constants.CacheConstants; -import org.opsli.core.cache.local.CacheUtil; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.enums.UserModelType; -import org.opsli.core.utils.UserUtil; -import org.opsli.plugins.cache.EhCachePlugin; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * 用户消息处理 - * - * @author Parker - * @date 2020-09-16 - */ -@Slf4j -public class UserHandler implements RedisPushSubHandler{ - - @Autowired - private EhCachePlugin ehCachePlugin; - - @Override - public PushSubType getType() { - return PushSubType.USER; - } - - @Override - public void handler(JSONObject msgJson) { - UserModelType userModelType = UserModelType.valueOf((String) - msgJson.get(MsgArgsType.USER_MODEL_TYPE.toString())); - - // 用户刷新 - if(UserModelType.USER_MODEL == userModelType){ - this.userHandler(msgJson); - } - // 用户角色刷新 - else if(UserModelType.USER_ROLES_MODEL == userModelType){ - this.userRolesHandler(msgJson); - } - // 用户权限刷新 - else if(UserModelType.USER_PERMS_MODEL == userModelType){ - this.userPermsHandler(msgJson); - } - // 用户菜单刷新 - else if(UserModelType.USER_MENU_MODEL == userModelType){ - this.userMenusHandler(msgJson); - } - - } - - /** - * 用户数据处理 - * @param msgJson 信息Json - */ - private void userHandler(JSONObject msgJson){ - JSONObject data = msgJson.getJSONObject(MsgArgsType.USER_MODEL_DATA.toString()); - // 数据为空则不执行 - if(data == null){ - return; - } - - // 获得用户ID 和 用户名 - String userId = (String) msgJson.get(MsgArgsType.USER_ID.toString()); - String username = (String) msgJson.get(MsgArgsType.USER_USERNAME.toString()); - if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(username) ){ - return; - } - - String cacheKeyById = CacheUtil.handleKey(UserUtil.PREFIX_ID + userId); - String cacheKeyByName = CacheUtil.handleKey(UserUtil.PREFIX_USERNAME + username); - - // 先删除 - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKeyById); - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKeyByName); - } - - /** - * 用户角色数据处理 - * @param msgJson 信息Json - */ - private void userRolesHandler(JSONObject msgJson){ - JSONArray dataArray = msgJson.getJSONArray(MsgArgsType.USER_MODEL_DATA.toString()); - // 数据为空则不执行 - if(dataArray == null || dataArray.isEmpty()){ - return; - } - - // 获得用户ID - String userId = (String) msgJson.get(MsgArgsType.USER_ID.toString()); - if(StringUtils.isEmpty(userId)){ - return; - } - - String cacheKey = CacheUtil.handleKey(UserUtil.PREFIX_ID_ROLES + userId); - - // 先删除 - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey); - } - - /** - * 用户权限数据处理 - * @param msgJson 信息Json - */ - private void userPermsHandler(JSONObject msgJson){ - JSONArray dataArray = msgJson.getJSONArray(MsgArgsType.USER_MODEL_DATA.toString()); - // 数据为空则不执行 - if(dataArray == null || dataArray.isEmpty()){ - return; - } - - // 获得用户ID - String userId = (String) msgJson.get(MsgArgsType.USER_ID.toString()); - if(StringUtils.isEmpty(userId)){ - return; - } - - String cacheKey = CacheUtil.handleKey(UserUtil.PREFIX_ID_PERMISSIONS + userId); - - // 先删除 - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey); - } - - /** - * 用户菜单数据处理 - * @param msgJson 信息Json - */ - private void userMenusHandler(JSONObject msgJson){ - JSONArray dataArray = msgJson.getJSONArray(MsgArgsType.USER_MODEL_DATA.toString()); - // 数据为空则不执行 - if(dataArray == null || dataArray.isEmpty()){ - return; - } - - // 获得用户ID - String userId = (String) msgJson.get(MsgArgsType.USER_ID.toString()); - if(StringUtils.isEmpty(userId)){ - return; - } - - String cacheKey = CacheUtil.handleKey(UserUtil.PREFIX_ID_MENUS + userId); - - // 先删除 - ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey); - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/CacheDataMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/CacheDataMsgFactory.java deleted file mode 100644 index e25dcd2dc5dd01bc1717aa74a80f8ab5d7cc2364..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/CacheDataMsgFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.msgs; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; -import org.opsli.core.cache.pushsub.entity.CacheDataEntity; -import org.opsli.core.cache.pushsub.enums.CacheHandleType; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; - -/** - * 热数据消息 - * - * @author Parker - * @date 2020-09-15 - */ -@Data -@Accessors(chain = true) -public final class CacheDataMsgFactory extends BaseSubMessage{ - - /** 通道 */ - private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL + RedisPushSubReceiver.CHANNEL; - - private CacheDataMsgFactory(){} - - /** - * 构建消息 热数据 - * @param cacheDataEntity 热数据对象 - * @param value 值 - * @param cacheHandleType 类型 - * @return 消息 - */ - public static BaseSubMessage createMsg(CacheDataEntity cacheDataEntity, Object value, - CacheHandleType cacheHandleType){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.CACHE_DATA_KEY.toString(),cacheDataEntity.getKey()); - jsonObj.put(MsgArgsType.CACHE_DATA_VALUE.toString(),value); - jsonObj.put(MsgArgsType.CACHE_DATA_TYPE.toString(), cacheHandleType.toString()); - - // 热点数据 - 系统数据 - baseSubMessage.build(CHANNEL, PushSubType.HOT_DATA.toString(), jsonObj); - return baseSubMessage; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/DictMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/DictMsgFactory.java deleted file mode 100644 index a5500e11042bafeb6d3387a91e4003537ec7dc36..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/DictMsgFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.msgs; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; -import org.opsli.api.wrapper.system.dict.DictWrapper; -import org.opsli.core.cache.pushsub.enums.CacheHandleType; -import org.opsli.core.cache.pushsub.enums.DictModelType; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; - -import java.util.List; - -/** - * 字典消息 - * - * @author Parker - * @date 2020-09-15 - */ -@Data -@Accessors(chain = true) -public final class DictMsgFactory extends BaseSubMessage{ - - /** 通道 */ - private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL; - - private DictMsgFactory(){} - - /** - * 构建消息 字典 - * @param dictWrapperModel 字典模型 - * @param cacheHandleType 缓存类型 - * @return 消息 - */ - public static BaseSubMessage createMsg(DictWrapper dictWrapperModel, CacheHandleType cacheHandleType){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.DICT_MODEL.toString(), dictWrapperModel); - jsonObj.put(MsgArgsType.DICT_MODEL_TYPE.toString(), DictModelType.OBJECT); - jsonObj.put(MsgArgsType.DICT_TYPE.toString(), cacheHandleType.toString()); - - // DICT 字典 - baseSubMessage.build(CHANNEL,PushSubType.DICT.toString(),jsonObj); - return baseSubMessage; - } - - /** - * 构建消息 字典 - * @param dictWrapperModels 字典模型集合 - * @param cacheHandleType 缓存类型 - * @return 消息 - */ - public static BaseSubMessage createMsg(List dictWrapperModels, CacheHandleType cacheHandleType){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.DICT_MODELS.toString(), dictWrapperModels); - jsonObj.put(MsgArgsType.DICT_MODEL_TYPE.toString(), DictModelType.COLLECTION); - jsonObj.put(MsgArgsType.DICT_TYPE.toString(), cacheHandleType.toString()); - - // DICT 字典 - baseSubMessage.build(CHANNEL,PushSubType.DICT.toString(),jsonObj); - return baseSubMessage; - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OptionMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OptionMsgFactory.java deleted file mode 100644 index 723df4884abf8b2d58d4e428c6d30d08505bedb6..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OptionMsgFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.msgs; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; -import org.opsli.api.wrapper.system.menu.MenuModel; -import org.opsli.api.wrapper.system.options.OptionsModel; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; - -/** - * 参数消息 - * - * @author Parker - * @date 2020-09-15 - */ -@Data -@Accessors(chain = true) -public final class OptionMsgFactory extends BaseSubMessage{ - - /** 通道 */ - private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL; - - private OptionMsgFactory(){} - - /** - * 构建消息 - 参数 - * @param optionsModel 参数模型 - * @return 消息 - */ - public static BaseSubMessage createOptionMsg(OptionsModel optionsModel){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.OPTION_CODE.toString(), optionsModel.getOptionCode()); - jsonObj.put(MsgArgsType.OPTION_MODEL_DATA.toString(), optionsModel); - - // 参数 - baseSubMessage.build(CHANNEL,PushSubType.OPTION.toString(),jsonObj); - return baseSubMessage; - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OrgMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OrgMsgFactory.java deleted file mode 100644 index 39a322526b7ac8b4b473937ab54bb225b9e53504..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OrgMsgFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.msgs; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; -import org.opsli.api.wrapper.system.user.UserOrgRefWebModel; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; - -/** - * 用户组织消息 - * - * @author Parker - * @date 2020-09-15 - */ -@Data -@Accessors(chain = true) -public final class OrgMsgFactory extends BaseSubMessage{ - - /** 通道 */ - private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL; - - private OrgMsgFactory(){} - - /** - * 构建消息 - 用户组织 - * @param orgRefModel 用户组织模型 - * @return 消息 - */ - public static BaseSubMessage createOrgMsg(UserOrgRefWebModel orgRefModel){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.ORG_USER_ID.toString(), orgRefModel.getUserId()); - jsonObj.put(MsgArgsType.ORG_USER_DATA.toString(), orgRefModel); - - // 组织 - baseSubMessage.build(CHANNEL,PushSubType.ORG.toString(),jsonObj); - return baseSubMessage; - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/TenantMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/TenantMsgFactory.java deleted file mode 100644 index 73124ef587fdbda7d1b493a685bbee0f36edcda1..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/TenantMsgFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.msgs; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; -import org.opsli.api.wrapper.system.tenant.TenantModel; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; - -/** - * 租户消息 - * - * @author Parker - * @date 2020-09-15 - */ -@Data -@Accessors(chain = true) -public final class TenantMsgFactory extends BaseSubMessage{ - - /** 通道 */ - private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL; - - private TenantMsgFactory(){} - - /** - * 构建消息 - 租户 - * @param tenantModel 租户模型 - * @return 消息 - */ - public static BaseSubMessage createTenantMsg(TenantModel tenantModel){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.TENANT_ID.toString(), tenantModel.getId()); - jsonObj.put(MsgArgsType.TENANT_DATA.toString(), tenantModel); - - // 租户 - baseSubMessage.build(CHANNEL,PushSubType.TENANT.toString(),jsonObj); - return baseSubMessage; - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/UserMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/UserMsgFactory.java deleted file mode 100644 index 3a65e9333841668e10c737b208bfb5a9d069a970..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/UserMsgFactory.java +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.msgs; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; -import org.opsli.api.wrapper.system.menu.MenuModel; -import org.opsli.api.wrapper.system.user.UserModel; -import org.opsli.core.cache.pushsub.enums.MsgArgsType; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.enums.UserModelType; -import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; - -import java.util.List; - -/** - * 用户消息 - * - * @author Parker - * @date 2020-09-15 - */ -@Data -@Accessors(chain = true) -public final class UserMsgFactory extends BaseSubMessage{ - - /** 通道 */ - private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL; - - private UserMsgFactory(){} - - /** - * 构建消息 - 用户 - * @param userModel 用户模型 - * @return 消息 - */ - public static BaseSubMessage createUserMsg(UserModel userModel){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.USER_ID.toString(), userModel.getId()); - jsonObj.put(MsgArgsType.USER_USERNAME.toString(), userModel.getUsername()); - jsonObj.put(MsgArgsType.USER_MODEL_TYPE.toString(), UserModelType.USER_MODEL.toString()); - jsonObj.put(MsgArgsType.USER_MODEL_DATA.toString(), userModel); - - // 用户 - baseSubMessage.build(CHANNEL,PushSubType.USER.toString(),jsonObj); - return baseSubMessage; - } - - /** - * 构建消息 - 用户角色 - * @param userId 用户ID - * @param roles 角色集合 - * @return 消息 - */ - public static BaseSubMessage createUserRolesMsg(String userId, List roles){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.USER_ID.toString(), userId); - jsonObj.put(MsgArgsType.USER_MODEL_TYPE.toString(), UserModelType.USER_ROLES_MODEL.toString()); - jsonObj.put(MsgArgsType.USER_MODEL_DATA.toString(), roles); - - // 用户 - baseSubMessage.build(CHANNEL,PushSubType.USER.toString(),jsonObj); - return baseSubMessage; - } - - /** - * 构建消息 - 用户权限 - * @param userId 用户ID - * @param perms 权限集合 - * @return 消息 - */ - public static BaseSubMessage createUserPermsMsg(String userId, List perms){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.USER_ID.toString(), userId); - jsonObj.put(MsgArgsType.USER_MODEL_TYPE.toString(), UserModelType.USER_PERMS_MODEL.toString()); - jsonObj.put(MsgArgsType.USER_MODEL_DATA.toString(), perms); - - // 用户 - baseSubMessage.build(CHANNEL,PushSubType.USER.toString(),jsonObj); - return baseSubMessage; - } - - /** - * 构建消息 - 用户菜单 - * @param userId 用户ID - * @param menus 菜单集合 - * @return 消息 - */ - public static BaseSubMessage createUserMenusMsg(String userId, List menus){ - BaseSubMessage baseSubMessage = new BaseSubMessage(); - // 数据 - JSONObject jsonObj = new JSONObject(); - jsonObj.put(MsgArgsType.USER_ID.toString(), userId); - jsonObj.put(MsgArgsType.USER_MODEL_TYPE.toString(), UserModelType.USER_MENU_MODEL.toString()); - jsonObj.put(MsgArgsType.USER_MODEL_DATA.toString(), menus); - - // 用户 - baseSubMessage.build(CHANNEL,PushSubType.USER.toString(),jsonObj); - return baseSubMessage; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/receiver/RedisPushSubReceiver.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/receiver/RedisPushSubReceiver.java deleted file mode 100644 index ab486250f2d8230cbe36bbf882e114e5bab52ff0..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/receiver/RedisPushSubReceiver.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.cache.pushsub.receiver; - -import cn.hutool.core.util.ClassUtil; -import com.alibaba.fastjson.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.opsli.common.enums.SystemInfo; -import org.opsli.core.cache.pushsub.enums.PushSubType; -import org.opsli.core.cache.pushsub.handler.RedisPushSubHandler; -import org.opsli.core.msg.CoreMsg; -import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage; -import org.opsli.plugins.redis.pushsub.receiver.BaseReceiver; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.lang.reflect.Modifier; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * Redis 消息订阅 更新本地缓存 - * 字典缓存更新 - * - * @author Parker - * @date 2020-09-15 - */ -@Slf4j -@Configuration -public class RedisPushSubReceiver extends BaseReceiver { - - /** Spring Bean 前缀 */ - public static final String SPRING_PREFIX = "redisPushSub_"; - - /** 监听信道 */ - public static final String CHANNEL = "opsli"; - - /** 处理方法集合 */ - private static final ConcurrentMap HANDLER_MAP = new ConcurrentHashMap<>(); - - - @Autowired - private AutowireCapableBeanFactory beanFactory; - - @Autowired - private DefaultListableBeanFactory defaultListableBeanFactory; - - public RedisPushSubReceiver() { - super(CHANNEL); - } - - @Bean - public void initRedisPushSubHandler(){ - - // 拿到state包下 实现了 SystemEventState 接口的,所有子类 - Set> clazzSet = ClassUtil.scanPackageBySuper( - RedisPushSubHandler.class.getPackage().getName(), - RedisPushSubHandler.class - ); - - for (Class aClass : clazzSet) { - // 位运算 去除抽象类 - if((aClass.getModifiers() & Modifier.ABSTRACT) != 0){ - continue; - } - - try { - Object obj = aClass.newInstance(); - - RedisPushSubHandler handler = (RedisPushSubHandler) obj; - - // 加入集合 - HANDLER_MAP.put(handler.getType(),handler); - - //将new出的对象放入Spring容器中 - defaultListableBeanFactory.registerSingleton(SPRING_PREFIX+aClass.getSimpleName(), obj); - - //自动注入依赖 - beanFactory.autowireBean(obj); - - } catch (Exception e){ - log.error(CoreMsg.REDIS_EXCEPTION_PUSH_SUB.getMessage()); - } - } - } - - - @Override - public void receiveMessage(String msg) { - if(msg == null || "".equals(msg)){ - return; - } - long beginTime = System.currentTimeMillis(); - // 替换 转意符 - String replaceAll = msg.replaceAll("\\\\", ""); - String substring = replaceAll.substring(1, replaceAll.length() - 1); - JSONObject msgJson = JSONObject.parseObject(substring); - String type = (String) msgJson.get(BaseSubMessage.BASE_TYPE); - String identifier = (String) msgJson.get(BaseSubMessage.BASE_ID); - // 本机不广播 - if(SystemInfo.INSTANCE.getSystemID().equals(identifier)){ - return; - } - PushSubType pt = PushSubType.valueOf(type); - RedisPushSubHandler redisPushSubHandler = HANDLER_MAP.get(pt); - if(redisPushSubHandler == null){ - return; - } - redisPushSubHandler.handler(msgJson); - long endTime = System.currentTimeMillis(); - log.info("订阅节点更新缓存 耗时(毫秒):{}",(endTime-beginTime)); - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/CacheDataAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/CacheDataAop.java deleted file mode 100644 index 4ccd6718ec7494999c15e069b160d4d0cb6b91b0..0000000000000000000000000000000000000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/CacheDataAop.java +++ /dev/null @@ -1,299 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.opsli.core.filters.aspect; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; -import com.google.common.collect.Lists; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.aspectj.lang.reflect.MethodSignature; -import org.opsli.api.base.warpper.ApiWrapper; -import org.opsli.common.annotation.hotdata.EnableHotData; -import org.opsli.common.annotation.hotdata.HotDataDel; -import org.opsli.common.annotation.hotdata.HotDataPut; -import org.opsli.common.constants.CacheConstants; -import org.opsli.core.cache.local.CacheUtil; -import org.opsli.core.cache.pushsub.entity.CacheDataEntity; -import org.opsli.core.cache.pushsub.enums.CacheHandleType; -import org.opsli.core.cache.pushsub.msgs.CacheDataMsgFactory; -import org.opsli.plugins.redis.RedisPlugin; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; - -import static org.opsli.common.constants.OrderConstants.HOT_DATA_ORDER; - -/** - * 热点数据 拦截处理 - * - * @author parker - * @date 2020-09-16 - */ -@Slf4j -@Order(HOT_DATA_ORDER) -@Aspect -@Component -public class CacheDataAop { - - @Autowired - private RedisPlugin redisPlugin; - - @Pointcut("@annotation(org.opsli.common.annotation.hotdata.HotDataPut)") - public void hotDataPut() { - } - - @Pointcut("@annotation(org.opsli.common.annotation.hotdata.HotDataDel)") - public void hotDataDel() { - } - - /** - * 切如 更新数据 - * @param point point - * @return Object - * @throws Throwable 异常 - */ - @Around("hotDataPut()") - public Object hotDataPutProcess(ProceedingJoinPoint point) throws Throwable { - Object[] args = point.getArgs(); - Object returnValue = point.proceed(args); - // 判断 方法上是否使用 EnableHotData注解 如果没有表示开启热数据 则直接跳过 - Annotation annotation = point.getTarget().getClass().getAnnotation(EnableHotData.class); - if(annotation == null){ - return returnValue; - } - - List cacheDataEntityList = this.putHandlerData(point, returnValue); - // 非法判断 - if(CollUtil.isEmpty(cacheDataEntityList)){ - return returnValue; - } - - for (CacheDataEntity cacheDataEntity : cacheDataEntityList) { - // 更新缓存数据 - // 热点数据 - boolean putRet = CacheUtil.put(CacheConstants.HOT_DATA_PREFIX +":"+ cacheDataEntity.getKey(), - returnValue); - if(putRet){ - // 广播缓存数据 - 通知其他服务器同步数据 - redisPlugin.sendMessage( - CacheDataMsgFactory.createMsg( - cacheDataEntity, returnValue, CacheHandleType.UPDATE) - ); - } - } - - return returnValue; - } - - - /** - * 切如 删除数据 和 逻辑删除上 - * @param point point - * @return Object - * @throws Throwable 异常 - */ - @Around("hotDataDel()") - public Object hotDataDelProcess(ProceedingJoinPoint point) throws Throwable { - Object[] args= point.getArgs(); - Object returnValue = point.proceed(args); - // 判断 方法上是否使用 EnableHotData注解 如果没有表示开启热数据 则直接跳过 - Annotation annotation = point.getTarget().getClass().getAnnotation(EnableHotData.class); - if(annotation == null){ - return returnValue; - } - - // 删除状态判断 - try { - Boolean ret = (Boolean) returnValue; - if(ret == null || !ret){ - return returnValue; - } - }catch (Exception e){ - log.error(e.getMessage(),e); - return returnValue; - } - - List cacheDataEntityList = this.delHandlerData(point, args); - // 非法判断 - if(CollUtil.isEmpty(cacheDataEntityList)){ - return returnValue; - } - - for (CacheDataEntity cacheDataEntity : cacheDataEntityList) { - // 更新缓存数据 - 删除缓存 - boolean delRet = CacheUtil.del(CacheConstants.HOT_DATA_PREFIX +":"+ cacheDataEntity.getKey()); - if(delRet){ - // 广播缓存数据 - 通知其他服务器同步数据 - redisPlugin.sendMessage( - CacheDataMsgFactory.createMsg( - cacheDataEntity, null, CacheHandleType.DELETE) - ); - } - } - - return returnValue; - } - - - // =========================================================================== - - - /*** - * PUT 处理数据 - * @param point point - */ - private List putHandlerData(ProceedingJoinPoint point, Object returnValue){ - // 这里 只对 继承了 ApiWrapper 的类做处理 - if(!(returnValue instanceof ApiWrapper)){ - return null; - } - - // 消息集合 后续可能会考虑 多消息存储 - List cacheDataEntities = Lists.newArrayListWithCapacity(1); - - // 报错不处理 - try { - // 获得方法 - Method objMethod = this.getMethod(point); - if(objMethod == null) { - return null; - } - - // 获取注解参数 - HotDataPut aCache = objMethod.getAnnotation(HotDataPut.class); - if(aCache != null){ - // 这里 只对 继承了 BaseEntity 的类做处理 - ApiWrapper apiWrapper = (ApiWrapper) returnValue; - - CacheDataEntity ret = new CacheDataEntity(apiWrapper.getId()); - // 存放数据 - this.putCacheData(cacheDataEntities, ret); - - return cacheDataEntities; - } - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return null; - } - - - /*** - * DEL 处理数据 - * @param point point - */ - private List delHandlerData(ProceedingJoinPoint point, Object[] args){ - if(args == null || args.length == 0){ - return null; - } - - // 消息集合 - List cacheDataEntities = Lists.newArrayListWithCapacity(args.length); - - // 报错不处理 - try { - // 获得方法 - Method objMethod = this.getMethod(point); - if(objMethod == null) { - return null; - } - - // 获取注解参数 - HotDataDel aCache= objMethod.getAnnotation(HotDataDel.class); - if(aCache != null){ - - List keyList = null; - - // 处理数据 - for (Object arg : args) { - if (arg instanceof ApiWrapper) { - // key 存储ID - ApiWrapper apiWrapper = Convert.convert(ApiWrapper.class, arg); - keyList = Convert.toList(String.class, apiWrapper.getId()); - } else if (arg instanceof Collection) { - try { - keyList = Lists.newArrayList(); - List baseEntityList = Convert.toList(ApiWrapper.class, arg); - for (ApiWrapper baseEntity : baseEntityList) { - keyList.add(baseEntity.getId()); - } - }catch (Exception e){ - log.error(e.getMessage(),e); - } - }else { - keyList = Convert.toList(String.class, arg); - } - } - - if(keyList != null && CollUtil.isNotEmpty(keyList)){ - for (String key : keyList) { - CacheDataEntity ret = new CacheDataEntity(key); - // 存放数据 - this.putCacheData(cacheDataEntities, ret); - } - } - - return cacheDataEntities; - } - }catch (Exception e){ - log.error(e.getMessage(),e); - } - return null; - } - - - // ===================== - - /** - * 获得方法 - * @param point point - * @return Method 方法 - */ - private Method getMethod(ProceedingJoinPoint point){ - Method m = null; - try { - String methodName= point.getSignature().getName(); - Class classTarget= point.getTarget().getClass(); - Class[] par=((MethodSignature) point.getSignature()).getParameterTypes(); - m = classTarget.getMethod(methodName, par); - }catch (Exception ignored){} - return m; - } - - /** - * 存放数据 - * @param cacheDataList 缓存数据集合 - * @param cacheData 缓存数据 - */ - private void putCacheData(List cacheDataList, CacheDataEntity cacheData){ - // 非法判断 - if(cacheDataList == null){ - return; - } - cacheDataList.add(cacheData); - } - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/ApiCryptoAsymmetricAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LoginCryptoAop.java similarity index 79% rename from opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/ApiCryptoAsymmetricAop.java rename to opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LoginCryptoAop.java index 1894f40393a7f86a243dd6132af0ee6bd201bcdb..59a48d6c5fc656acc88855b6d7b62c69734975e3 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/ApiCryptoAsymmetricAop.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LoginCryptoAop.java @@ -21,8 +21,11 @@ import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.TypeUtil; import lombok.extern.slf4j.Slf4j; import opsli.plugins.crypto.CryptoPlugin; +import opsli.plugins.crypto.enums.CryptoSymmetricType; import opsli.plugins.crypto.model.CryptoAsymmetric; +import opsli.plugins.crypto.model.CryptoSymmetric; import opsli.plugins.crypto.strategy.CryptoAsymmetricService; +import opsli.plugins.crypto.strategy.CryptoSymmetricService; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -30,7 +33,7 @@ import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.opsli.api.base.encrypt.BaseEncrypt; import org.opsli.api.base.result.ResultVo; -import org.opsli.common.annotation.ApiCryptoAsymmetric; +import org.opsli.common.annotation.LoginCrypto; import org.opsli.common.exception.ServiceException; import org.opsli.core.msg.CoreMsg; import org.opsli.core.options.CryptoConfigFactory; @@ -45,7 +48,7 @@ import java.util.Map; import static org.opsli.common.constants.OrderConstants.ENCRYPT_ADN_DECRYPT_AOP_SORT; /** - * Api非对称加解密 拦截处理 + * 登录加解密 拦截处理 * * @author parker * @date 2021-01-23 @@ -54,9 +57,9 @@ import static org.opsli.common.constants.OrderConstants.ENCRYPT_ADN_DECRYPT_AOP_ @Order(ENCRYPT_ADN_DECRYPT_AOP_SORT) @Aspect @Component -public class ApiCryptoAsymmetricAop { +public class LoginCryptoAop { - @Pointcut("@annotation(org.opsli.common.annotation.ApiCryptoAsymmetric)") + @Pointcut("@annotation(org.opsli.common.annotation.LoginCrypto)") public void encryptAndDecrypt() { } @@ -75,12 +78,12 @@ public class ApiCryptoAsymmetricAop { // 获得 方法 Method method = signature.getMethod(); // 获得方法注解 - ApiCryptoAsymmetric annotation = - method.getAnnotation(ApiCryptoAsymmetric.class); + LoginCrypto annotation = + method.getAnnotation(LoginCrypto.class); // 获得非对称加解密 执行器 CryptoAsymmetricService asymmetric = null; - // 加解密模型 + // 非对称加解密模型 CryptoAsymmetric cryptoAsymmetric = null; if(annotation != null && annotation.enable()){ asymmetric = CryptoPlugin.getAsymmetric(); @@ -88,7 +91,7 @@ public class ApiCryptoAsymmetricAop { } // 1. 请求解密 - if(annotation != null && annotation.enable() && annotation.requestDecrypt()){ + if(annotation != null && annotation.enable()){ if(cryptoAsymmetric != null){ enterDecrypt(args, method, asymmetric, cryptoAsymmetric); } @@ -97,10 +100,16 @@ public class ApiCryptoAsymmetricAop { // 2. 执行方法 returnValue = point.proceed(args); - // 3. 返回加密 - if(annotation != null && annotation.enable() && annotation.responseEncrypt()){ + // 3. 返回加密 返回加密为对称加密 + if(annotation != null && annotation.enable()){ if(cryptoAsymmetric != null){ - returnValue = resultEncrypt(returnValue, asymmetric, cryptoAsymmetric); + CryptoSymmetricService symmetric = CryptoPlugin.getSymmetric(); + CryptoSymmetric symmetricModel = symmetric.createNilModel(); + symmetricModel.setCryptoType(CryptoSymmetricType.DES); + symmetricModel.setPrivateKey(cryptoAsymmetric.getPublicKey()); + + // 执行加密操作 + returnValue = resultEncrypt(returnValue, symmetric, symmetricModel); } } return returnValue; @@ -152,12 +161,12 @@ public class ApiCryptoAsymmetricAop { /** * 出参加密 * @param returnValue 出参(对象) - * @param asymmetric 非对称加解密执行器 - * @param cryptoModel 非对称加解密模型 + * @param symmetric 对称加解密执行器 + * @param cryptoModel 对称加解密模型 * @return Object */ @SuppressWarnings("unchecked") - private Object resultEncrypt(Object returnValue, CryptoAsymmetricService asymmetric, CryptoAsymmetric cryptoModel) { + private Object resultEncrypt(Object returnValue, CryptoSymmetricService symmetric, CryptoSymmetric cryptoModel) { if(returnValue != null){ try { // 执行加密过程 @@ -165,10 +174,10 @@ public class ApiCryptoAsymmetricAop { // 重新赋值 data ResultVo ret = (ResultVo) returnValue; ret.setData( - asymmetric.encrypt(cryptoModel, ret.getData()) + symmetric.encrypt(cryptoModel, ret.getData()) ); }else { - returnValue = asymmetric.encrypt(cryptoModel, returnValue); + returnValue = symmetric.encrypt(cryptoModel, returnValue); } }catch (Exception e){ // 非对称加密失败 diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/Page.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/Page.java index afa614123355406bea4f171d5b001c4e8a4a1fb5..7a8c32a2f0e0073c4b8bca57a4632023445a5b2d 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/Page.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/persistence/Page.java @@ -80,8 +80,8 @@ public class Page extends PageSeriali /** * 分页函数 不统计 count */ - public void pageHelperBegin(boolean countFlag){ - PageHelper.startPage(this.pageNo,this.pageSize, countFlag); + public void pageHelperBegin(boolean isByCount){ + PageHelper.startPage(this.pageNo,this.pageSize, isByCount); } /** diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java index a6b06c299dee6addfc5d72bededdd86a67e8740a..c06a581e4b5b4b6d0c965bb3045a73baf9f798ad 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java @@ -23,7 +23,7 @@ import com.wf.captcha.SpecCaptcha; import com.wf.captcha.base.Captcha; import org.apache.commons.lang3.StringUtils; import org.opsli.common.exception.TokenException; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.TokenMsg; import org.opsli.plugins.redis.RedisPlugin; @@ -98,8 +98,11 @@ public class CaptchaUtil { // 生成验证码 Captcha captcha = captchaStrategy.createCaptcha(); + // 缓存Key + String cacheKey = CacheUtil.formatKey(PREFIX + uuid); + // 保存至缓存 - boolean ret = redisPlugin.put(CacheUtil.getPrefixName() + PREFIX + uuid, captcha.text(), TIME_OUT); + boolean ret = redisPlugin.put(cacheKey, captcha.text(), TIME_OUT); if(ret){ // 输出 captcha.out(out); @@ -127,8 +130,11 @@ public class CaptchaUtil { throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_CODE_NULL); } + // 缓存Key + String cacheKey = CacheUtil.formatKey(PREFIX + uuid); + // 验证码 - String codeTemp = (String) redisPlugin.get(CacheUtil.getPrefixName() + PREFIX + uuid); + String codeTemp = (String) redisPlugin.get(cacheKey); if (StringUtils.isEmpty(codeTemp)) { throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_NULL); } @@ -156,8 +162,11 @@ public class CaptchaUtil { return false; } + // 缓存Key + String cacheKey = CacheUtil.formatKey(PREFIX + uuid); + //删除验证码 - return redisPlugin.del(CacheUtil.getPrefixName() + PREFIX + uuid); + return redisPlugin.del(cacheKey); } // ====================== diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java index 01c636108c1875112183ebedf2bd02db6684308a..704f1ed5b52f35507fd19340c84c6ed824d5df6a 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java @@ -19,19 +19,20 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.opsli.api.base.result.ResultVo; import org.opsli.api.web.system.dict.DictDetailApi; import org.opsli.api.wrapper.system.dict.DictDetailModel; import org.opsli.api.wrapper.system.dict.DictWrapper; -import org.opsli.common.constants.DictConstants; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.common.constants.RedisConstants; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.cache.SecurityCache; import org.opsli.core.msg.CoreMsg; -import org.opsli.plugins.redis.RedisPlugin; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.List; @@ -56,6 +57,8 @@ public class DictUtil { /** 字典Service */ private static DictDetailApi dictDetailApi; + /** Redis */ + private static RedisTemplate redisTemplate; /** * 根据 字典值 取 字典名称 @@ -70,75 +73,30 @@ public class DictUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = DictConstants.CACHE_PREFIX_VALUE + typeCode; - // 缓存Key + VALUE - String cacheKeyVal = cacheKey + ":" + dictValue; - - // 字典名称 - String dictName = null; - - DictDetailModel cacheModel = CacheUtil.getHash(DictDetailModel.class, cacheKey, - dictValue); - // 如果缓存有值 直接返回 - if (cacheModel != null && - StringUtils.isNotEmpty(cacheModel.getDictName())){ - return cacheModel.getDictName(); - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_DICT_VALUE + typeCode); - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKeyVal); - if(hasNilFlag){ - return defaultVal; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKeyVal)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); + Object cache = SecurityCache.hGet(redisTemplate, cacheKey, dictValue, (k) -> { + // 查询数据库 并保存到缓存内 + ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); + if (!resultVo.isSuccess()) { return null; } - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - cacheModel = CacheUtil.getHash(DictDetailModel.class, cacheKey, - dictValue); - // 如果缓存有值 直接返回 - if (cacheModel != null && - StringUtils.isNotEmpty(cacheModel.getDictName())){ - return cacheModel.getDictName(); - } - - // 查询数据库 并保存到缓存内 - ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if(resultVo.isSuccess()){ - List dictDetailModels = resultVo.getData(); - for (DictDetailModel model : dictDetailModels) { - if(model.getDictValue().equals(dictValue)){ - // 保存至缓存 - DictWrapper dictWrapper = DictUtil.putByModel(model); - // 缓存名 - dictName = dictWrapper.getDictName(); - break; - } + List dictDetailModels = resultVo.getData(); + for (DictDetailModel model : dictDetailModels) { + if (model.getDictValue().equals(dictValue)) { + // 转化Model + return DictUtil.formatModel(model); } } + return null; + }); - }catch (Exception e){ - log.error(e.getMessage(),e); + if(null == cache){ return defaultVal; - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKeyVal); } - - // 如果名称还是 为空 则赋默认值 - if(StringUtils.isEmpty(dictName)){ - // 加入缓存防穿透 - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKeyVal); - dictName = defaultVal; - } - return dictName; + DictWrapper dictWrapper = Convert.convert(DictWrapper.class, cache); + return dictWrapper.getDictName(); } /** @@ -153,75 +111,32 @@ public class DictUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - // 缓存Key - String cacheKey = DictConstants.CACHE_PREFIX_NAME + typeCode; - // 缓存Key + VALUE - String cacheKeyVal = cacheKey + ":" + dictName; - - // 字典值 - String dictValue = null; - - DictDetailModel cacheModel = CacheUtil.getHash(DictDetailModel.class, cacheKey, - dictName); - // 如果缓存有值 直接返回 - if (cacheModel != null && - StringUtils.isNotEmpty(cacheModel.getDictValue())){ - return cacheModel.getDictValue(); - } - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKeyVal); - if(hasNilFlag){ - return defaultVal; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_DICT_NAME + typeCode); - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKeyVal)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); + Object cache = SecurityCache.hGet(redisTemplate, cacheKey, dictName, (k) -> { + // 查询数据库 并保存到缓存内 + ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); + if (!resultVo.isSuccess()) { return null; } - cacheModel = CacheUtil.getHash(DictDetailModel.class, cacheKey, - dictName); - // 如果缓存有值 直接返回 - if (cacheModel != null && - StringUtils.isNotEmpty(cacheModel.getDictValue())){ - return cacheModel.getDictValue(); - } - - // 查询数据库 并保存到缓存内 - ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if(resultVo.isSuccess()){ - List dictDetailModels = resultVo.getData(); - for (DictDetailModel model : dictDetailModels) { - if(model.getDictName().equals(dictName)){ - // 保存至缓存 - DictWrapper dictWrapper = DictUtil.putByModel(model); - // 值 - dictValue = dictWrapper.getDictValue(); - break; - } + List dictDetailModels = resultVo.getData(); + for (DictDetailModel model : dictDetailModels) { + if (model.getDictName().equals(dictName)) { + // 转化Model + return DictUtil.formatModel(model); } } + return null; + }); - }catch (Exception e){ - log.error(e.getMessage(),e); + if(null == cache){ return defaultVal; - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKeyVal); - } - - // 如果值还是 为空 则赋默认值 - if(StringUtils.isEmpty(dictValue)){ - // 加入缓存防穿透 - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKeyVal); - dictValue = defaultVal; } - return dictValue; + DictWrapper dictWrapper = Convert.convert(DictWrapper.class, cache); + return dictWrapper.getDictValue(); } /** @@ -235,134 +150,36 @@ public class DictUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = DictConstants.CACHE_PREFIX_NAME + typeCode; - - // 处理集合数据 - List dictWrapperModels = handleDictList( - CacheUtil.getHashAll(cacheKey), typeCode); - if(CollUtil.isNotEmpty(dictWrapperModels)){ - return sortDictWrappers(dictWrapperModels); - } - - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return sortDictWrappers(dictWrapperModels); - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return sortDictWrappers(dictWrapperModels); - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - // 处理集合数据 - dictWrapperModels = handleDictList( - CacheUtil.getHashAll(cacheKey), typeCode); - if(CollUtil.isNotEmpty(dictWrapperModels)){ - return sortDictWrappers(dictWrapperModels); - } - + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_DICT_VALUE + typeCode); + Map dictCacheMap = SecurityCache.hGetAll(redisTemplate, cacheKey, (k) -> { // 查询数据库 并保存到缓存内 ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if(resultVo.isSuccess()){ - List dictDetailModels = resultVo.getData(); - // 处理数据库查询数据 - if(CollUtil.isNotEmpty(dictDetailModels)){ - dictWrapperModels = Lists.newArrayListWithCapacity(dictDetailModels.size()); - for (DictDetailModel model : dictDetailModels) { - // 保存至缓存 - DictWrapper dictWrapper = DictUtil.putByModel(model); - dictWrapperModels.add(dictWrapper); - } - - return sortDictWrappers(dictWrapperModels); - } + if (!resultVo.isSuccess()) { + return null; } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + List dictDetailModels = resultVo.getData(); + Map dictMap = Maps.newHashMapWithExpectedSize(dictDetailModels.size()); + for (DictDetailModel model : dictDetailModels) { + dictMap.put(model.getDictValue(), model); + } + return dictMap; + }); - // 如果值还是 为空 则赋默认值 - if(CollUtil.isEmpty(dictWrapperModels)){ - // 加入缓存防穿透 - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - } + List dictWrappers = handleDictList(dictCacheMap, typeCode); // 排序 - return sortDictWrappers(dictWrapperModels); + return sortDictWrappers(dictWrappers); } - /** - * 字典排序 - * @param dictWrapperModels 字典Model - * @return List - */ - private static List sortDictWrappers(List dictWrapperModels) { - // 非法判读 - if(dictWrapperModels == null){ - return null; - } - ListUtil.sort(dictWrapperModels, (o1, o2) -> { - int oInt1 = Integer.MAX_VALUE; - int oInt2 = Integer.MAX_VALUE; - if(o1 != null && o1.getModel() != null){ - oInt1 = o1.getModel().getSortNo()==null?oInt1:o1.getModel().getSortNo(); - } - if(o2 != null && o2.getModel() != null){ - oInt2 = o2.getModel().getSortNo()==null?oInt2:o2.getModel().getSortNo(); - } - return Integer.compare(oInt1, oInt2); - }); - return dictWrapperModels; - } // =============== - /** - * 删除 字典 - * @param model 字典模型 - */ - private static DictWrapper putByModel(DictDetailModel model){ - DictWrapper dictWrapperModel = new DictWrapper(); - dictWrapperModel.setTypeCode(model.getTypeCode()); - dictWrapperModel.setDictName(model.getDictName()); - dictWrapperModel.setDictValue(model.getDictValue()); - dictWrapperModel.setModel(model); - // 保存至缓存 - DictUtil.put(dictWrapperModel); - return dictWrapperModel; - } - - /** - * 删除 字典 - * @param model 字典模型 - */ - public static void put(DictWrapper model){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 清除缓存 - DictUtil.del(model); - CacheUtil.putHash(DictConstants.CACHE_PREFIX_NAME + model.getTypeCode(), - model.getDictName(), model.getModel()); - CacheUtil.putHash(DictConstants.CACHE_PREFIX_VALUE + model.getTypeCode(), - model.getDictValue(), model.getModel()); - } /** * 删除 字典 @@ -378,60 +195,29 @@ public class DictUtil { return true; } - boolean hasNilFlagByName = CacheUtil.hasNilFlag(DictConstants.CACHE_PREFIX_NAME + - model.getTypeCode() + ":" + model.getDictName()); - boolean hasNilFlagByValue = CacheUtil.hasNilFlag(DictConstants.CACHE_PREFIX_VALUE + - model.getTypeCode() + ":" + model.getDictValue()); + // 缓存Key + String cacheKeyByValue = CacheUtil.formatKey( + RedisConstants.PREFIX_DICT_VALUE + model.getTypeCode()); + // 缓存Key + String cacheKeyByName = CacheUtil.formatKey( + RedisConstants.PREFIX_DICT_NAME + model.getTypeCode()); - DictWrapper dictByName = CacheUtil.getHash(DictWrapper.class, - DictConstants.CACHE_PREFIX_NAME + model.getTypeCode(), - model.getDictName()); - DictWrapper dictByValue = CacheUtil.getHash(DictWrapper.class, - DictConstants.CACHE_PREFIX_VALUE + model.getTypeCode(), - model.getDictValue()); // 计数器 - int count = 0; - if (hasNilFlagByName){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(DictConstants.CACHE_PREFIX_NAME + - model.getTypeCode() + ":" + model.getDictName()); + int count = 2; + { + boolean tmp = SecurityCache.hDel(redisTemplate, cacheKeyByValue, model.getDictValue()); if(tmp){ count--; } } - if (hasNilFlagByValue){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(DictConstants.CACHE_PREFIX_VALUE + - model.getTypeCode() + ":" + model.getDictValue()); + { + boolean tmp = SecurityCache.hDel(redisTemplate, cacheKeyByName, model.getDictName()); if(tmp){ count--; } } - - if (dictByName != null){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delHash(DictConstants.CACHE_PREFIX_NAME + - model.getTypeCode(), model.getDictName()); - if(tmp){ - count--; - } - } - - if (dictByValue != null){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delHash(DictConstants.CACHE_PREFIX_VALUE + - model.getTypeCode(), model.getDictValue()); - if(tmp){ - count--; - } - } - return count == 0; } @@ -450,15 +236,53 @@ public class DictUtil { return true; } - // 计数器 - int count = dictWrapperList.size(); - for (DictWrapper dictWrapperModel : dictWrapperList) { - boolean tmp = DictUtil.del(dictWrapperModel); - if(tmp){ - count--; - } + // 缓存Key + String cacheKeyByValue = CacheUtil.formatKey( + RedisConstants.PREFIX_DICT_VALUE + typeCode); + // 缓存Key + String cacheKeyByName = CacheUtil.formatKey( + RedisConstants.PREFIX_DICT_NAME + typeCode); + + return SecurityCache.removeMore(redisTemplate, cacheKeyByValue, cacheKeyByName); + } + + + /** + * 格式化 字典 + * @param model 字典模型 + */ + private static DictWrapper formatModel(DictDetailModel model){ + DictWrapper dictWrapperModel = new DictWrapper(); + dictWrapperModel.setTypeCode(model.getTypeCode()); + dictWrapperModel.setDictName(model.getDictName()); + dictWrapperModel.setDictValue(model.getDictValue()); + dictWrapperModel.setModel(model); + return dictWrapperModel; + } + + /** + * 字典排序 + * @param dictWrapperModels 字典Model + * @return List + */ + private static List sortDictWrappers(List dictWrapperModels) { + // 非法判读 + if(dictWrapperModels == null){ + return null; } - return count == 0; + + ListUtil.sort(dictWrapperModels, (o1, o2) -> { + int oInt1 = Integer.MAX_VALUE; + int oInt2 = Integer.MAX_VALUE; + if(o1 != null && o1.getModel() != null){ + oInt1 = o1.getModel().getSortNo()==null?oInt1:o1.getModel().getSortNo(); + } + if(o2 != null && o2.getModel() != null){ + oInt2 = o2.getModel().getSortNo()==null?oInt2:o2.getModel().getSortNo(); + } + return Integer.compare(oInt1, oInt2); + }); + return dictWrapperModels; } /*** @@ -496,9 +320,10 @@ public class DictUtil { * 初始化 */ @Autowired - public void init(DictDetailApi dictDetailApi) { + public void init(DictDetailApi dictDetailApi, + RedisTemplate redisTemplate) { DictUtil.dictDetailApi = dictDetailApi; - + DictUtil.redisTemplate = redisTemplate; IS_INIT = true; } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java index 159f36f0c01495c5f9f7b6cec05be7a706676f43..4ad19619469fe97aa19761222ec916e6bc347ca5 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java @@ -16,7 +16,7 @@ package org.opsli.core.utils; import lombok.extern.slf4j.Slf4j; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; import org.opsli.core.msg.CoreMsg; import org.opsli.plugins.redisson.RedissonLock; import org.springframework.beans.factory.annotation.Autowired; @@ -60,7 +60,9 @@ public class DistributedLockUtil { boolean isLock = true; // 分布式上锁 if(REDISSON_LOCK != null){ - isLock = REDISSON_LOCK.tryLock(CacheUtil.getPrefixName() + lockName, LEASE_TIME); + // 缓存Key + String cacheKey = CacheUtil.formatKey(lockName); + isLock = REDISSON_LOCK.tryLock(cacheKey, LEASE_TIME); } return isLock; } @@ -76,7 +78,9 @@ public class DistributedLockUtil { // 释放锁 if(REDISSON_LOCK != null){ - REDISSON_LOCK.unlockByThread(CacheUtil.getPrefixName() + lockName); + // 缓存Key + String cacheKey = CacheUtil.formatKey(lockName); + REDISSON_LOCK.unlockByThread(cacheKey); } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java index e8d7bd3059f25d559c7d4e9265bbd31c1820e462..b6bc8f918becb0bd0c1cbea96c4788d32ece9856 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java @@ -15,16 +15,20 @@ */ package org.opsli.core.utils; +import cn.hutool.core.convert.Convert; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.opsli.api.base.result.ResultVo; import org.opsli.api.web.system.menu.MenuApi; import org.opsli.api.wrapper.system.menu.MenuModel; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.common.constants.RedisConstants; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.cache.SecurityCache; import org.opsli.core.msg.CoreMsg; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @@ -41,15 +45,14 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @Lazy(false) public class MenuUtil { - /** 前缀 */ - public static final String PREFIX_CODE = "menu:code:"; - /** 菜单 Api */ private static MenuApi menuApi; /** 增加初始状态开关 防止异常使用 */ private static boolean IS_INIT; + private static RedisTemplate redisTemplate; + /** * 根据 权限 获得菜单 * @param permissions 权限 @@ -60,57 +63,20 @@ public class MenuUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - // 缓存Key - String cacheKey = PREFIX_CODE + permissions; - - // 先从缓存里拿 - MenuModel menuModel = CacheUtil.getTimed(MenuModel.class, cacheKey); - if (menuModel != null){ - return menuModel; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - menuModel = CacheUtil.getTimed(MenuModel.class, cacheKey); - if (menuModel != null){ - return menuModel; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_MENU_CODE + permissions); + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 ResultVo resultVo = menuApi.getByPermissions(permissions); - if(resultVo.isSuccess()){ - menuModel = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, menuModel); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(menuModel == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } - - return menuModel; + return Convert.convert(MenuModel.class, cache); } @@ -130,46 +96,24 @@ public class MenuUtil { return true; } - // 计数器 - int count = 0; - - MenuModel model = CacheUtil.getTimed(MenuModel.class, PREFIX_CODE + menu.getPermissions()); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + menu.getPermissions()); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_CODE + menu.getPermissions()); - if(tmp){ - count--; - } - } - - if(model != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_CODE + menu.getPermissions()); - if(tmp){ - count--; - } - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_MENU_CODE + menu.getPermissions()); - return count == 0; + // 删除缓存 + return SecurityCache.remove(redisTemplate, cacheKey); } - - // ===================================== /** * 初始化 */ @Autowired - public void init(MenuApi menuApi) { + public void init(MenuApi menuApi, + RedisTemplate redisTemplate) { MenuUtil.menuApi = menuApi; - + MenuUtil.redisTemplate = redisTemplate; IS_INIT = true; } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java index 0d8e991c6759d65f1282cb855344006c92fb9765..96bb2d01654599fc05528e79d8587f455f18d3ad 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java @@ -27,12 +27,15 @@ import org.opsli.api.base.result.ResultVo; import org.opsli.api.web.system.options.OptionsApi; import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.common.annotation.OptionDict; +import org.opsli.common.constants.RedisConstants; import org.opsli.common.enums.OptionsType; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.cache.SecurityCache; import org.opsli.core.msg.CoreMsg; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.lang.reflect.Field; @@ -54,9 +57,6 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @Lazy(false) public class OptionsUtil { - /** 前缀 */ - public static final String PREFIX_CODE = "options:code"; - /** 参数 Api */ private static OptionsApi optionsApi; @@ -66,6 +66,8 @@ public class OptionsUtil { /** 增加初始状态开关 防止异常使用 */ private static boolean IS_INIT; + private static RedisTemplate redisTemplate; + /** * 根据 optionsType 枚举 获得参数 * @param optionsType 枚举类 @@ -137,58 +139,18 @@ public class OptionsUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = PREFIX_CODE; - // 缓存Key + VALUE - String cacheKeyVal = cacheKey + ":" + optionCode; - - // 先从缓存里拿 - OptionsModel model = CacheUtil.getHash(OptionsModel.class, cacheKey, optionCode); - if (model != null){ - return model; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKeyVal); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKeyVal)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - model = CacheUtil.getHash(OptionsModel.class, cacheKey, optionCode); - if (model != null){ - return model; - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_OPTIONS_CODE); + Object cache = SecurityCache.hGet(redisTemplate, cacheKey, optionCode, (k) -> { // 查询数据库 ResultVo resultVo = optionsApi.getByCode(optionCode); - if(resultVo.isSuccess()){ - model = resultVo.getData(); - // 存入缓存 - CacheUtil.putHash(cacheKey, optionCode, model); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKeyVal); - } - - if(model == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKeyVal); - return null; - } + return resultVo.getData(); + }); - return model; + return Convert.convert(OptionsModel.class, cache); } // ============== 刷新缓存 ============== @@ -208,36 +170,10 @@ public class OptionsUtil { } // 缓存Key - String cacheKey = PREFIX_CODE; - // 缓存Key + VALUE - String cacheKeyVal = cacheKey + ":" + option.getOptionCode(); - - // 计数器 - int count = 0; - - OptionsModel model = CacheUtil.getHash(OptionsModel.class, cacheKey, option.getOptionCode()); - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKeyVal); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(cacheKeyVal); - if(tmp){ - count--; - } - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_OPTIONS_CODE); - if(model != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.delHash(cacheKey, option.getOptionCode()); - if(tmp){ - count--; - } - } - - return count == 0; + // 删除缓存 + return SecurityCache.hDel(redisTemplate, cacheKey, option.getOptionCode()); } /** @@ -292,9 +228,10 @@ public class OptionsUtil { * 初始化 */ @Autowired - public void init(OptionsApi optionsApi) { + public void init(OptionsApi optionsApi, + RedisTemplate redisTemplate) { OptionsUtil.optionsApi = optionsApi; - + OptionsUtil.redisTemplate = redisTemplate; IS_INIT = true; } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/SearchHisUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/SearchHisUtil.java index 117376e1f726211f45dd3df6d6c9d3ea4628d238..d2c169d98bceab7094ae10e69b7dbf9d5f81e8a5 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/SearchHisUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/SearchHisUtil.java @@ -19,7 +19,8 @@ import cn.hutool.core.collection.CollUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.opsli.api.wrapper.system.user.UserModel; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.common.constants.RedisConstants; +import org.opsli.core.cache.CacheUtil; import org.opsli.core.msg.CoreMsg; import org.opsli.plugins.redis.RedisPlugin; import org.springframework.beans.factory.annotation.Autowired; @@ -48,8 +49,6 @@ public class SearchHisUtil { /** 搜索历史缓存数据KEY */ private static final int DEFAULT_COUNT = 10; - /** 缓存前缀 */ - private static final String CACHE_PREFIX = "his:username:"; /** Redis插件 */ private static RedisPlugin redisPlugin; @@ -79,7 +78,7 @@ public class SearchHisUtil { // 获得当前用户 UserModel user = UserUtil.getUser(); - String cacheKey = CacheUtil.getPrefixName() + CACHE_PREFIX + user.getUsername() + ":" + key; + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_HIS_USERNAME + user.getUsername() + ":" + key); return redisPlugin.zReverseRange(cacheKey, 0, count - 1); } @@ -109,7 +108,7 @@ public class SearchHisUtil { } - String cacheKey = CacheUtil.getPrefixName() + CACHE_PREFIX + user.getUsername() + ":" + key; + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_HIS_USERNAME + user.getUsername() + ":" + key); String val = values[0]; // 记录 diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java index b1cff0584aed7122acaa0ffef45615d3318e79ce..f76fad2a3cb043fa861a60c555bb0dcb9a68afa5 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/TenantUtil.java @@ -15,16 +15,19 @@ */ package org.opsli.core.utils; +import cn.hutool.core.convert.Convert; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.opsli.api.base.result.ResultVo; import org.opsli.api.web.system.tenant.TenantApi; import org.opsli.api.wrapper.system.tenant.TenantModel; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.cache.SecurityCache; import org.opsli.core.msg.CoreMsg; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @@ -53,6 +56,8 @@ public class TenantUtil { /** 增加初始状态开关 防止异常使用 */ private static boolean IS_INIT; + private static RedisTemplate redisTemplate; + /** * 根据 tenantId 获得租户 * @param tenantId 租户ID @@ -64,56 +69,20 @@ public class TenantUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = PREFIX_CODE + tenantId; - - // 先从缓存里拿 - TenantModel tenantModel = CacheUtil.getTimed(TenantModel.class, cacheKey); - if (tenantModel != null){ - return tenantModel; - } + String cacheKey = CacheUtil.formatKey(PREFIX_CODE + tenantId); - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - tenantModel = CacheUtil.getTimed(TenantModel.class, cacheKey); - if (tenantModel != null){ - return tenantModel; - } + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 ResultVo resultVo = tenantApi.getTenantByUsable(tenantId); - if(resultVo.isSuccess()){ - tenantModel = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, tenantModel); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } - if(tenantModel == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } + return resultVo.getData(); + }, true); - return tenantModel; + return Convert.convert(TenantModel.class, cache); } @@ -133,32 +102,10 @@ public class TenantUtil { return true; } - // 计数器 - int count = 0; - - TenantModel tenantModel = CacheUtil.getTimed(TenantModel.class, PREFIX_CODE + tenantId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + tenantId); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_CODE + tenantId); - if(tmp){ - count--; - } - } - - if(tenantModel != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_CODE + tenantId); - if(tmp){ - count--; - } - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(PREFIX_CODE + tenantId); - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } @@ -168,9 +115,10 @@ public class TenantUtil { * 初始化 */ @Autowired - public void init(TenantApi tenantApi) { + public void init(TenantApi tenantApi, + RedisTemplate redisTemplate) { TenantUtil.tenantApi = tenantApi; - + TenantUtil.redisTemplate = redisTemplate; IS_INIT = true; } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java index 47e84aa6a4444b63c1faf2b1f27f307c0576033e..c6a6e865f46c9e9876d19a570b1b4b5c1cf23293 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java @@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.opsli.api.base.result.ResultVo; import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.constants.RedisConstants; import org.opsli.common.constants.SignConstants; import org.opsli.common.constants.TokenConstants; import org.opsli.common.constants.TokenTypeConstants; @@ -35,7 +36,7 @@ import org.opsli.common.enums.LoginLimitRefuse; import org.opsli.common.exception.TokenException; import org.opsli.core.api.TokenThreadLocal; import org.opsli.core.autoconfigure.properties.GlobalProperties; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.TokenMsg; import org.opsli.plugins.redis.RedisPlugin; @@ -64,12 +65,6 @@ public class UserTokenUtil { /** token 缓存名 */ public static final String TOKEN_NAME = TokenConstants.ACCESS_TOKEN; - /** 缓存前缀 */ - private static final String TICKET_PREFIX = "ticket:"; - /** 账号失败次数 */ - public static final String ACCOUNT_SLIP_COUNT_PREFIX = "account:slip:count:"; - /** 账号失败锁定KEY */ - public static final String ACCOUNT_SLIP_LOCK_PREFIX = "account:slip:lock:"; /** 限制登录数量 -1 为无限大 */ public static final int ACCOUNT_LIMIT_INFINITE = -1; /** 登录配置信息 */ @@ -100,8 +95,8 @@ public class UserTokenUtil { // 如果当前登录开启 数量限制 if(LOGIN_PROPERTIES.getLimitCount() > ACCOUNT_LIMIT_INFINITE){ // 当前用户已存在 Token数量 - Long ticketLen = redisPlugin.sSize(CacheUtil.getPrefixName() + - TICKET_PREFIX + user.getUsername()); + Long ticketLen = redisPlugin.sSize( + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername())); if(ticketLen !=null && ticketLen >= LOGIN_PROPERTIES.getLimitCount()){ // 如果是拒绝后者 则直接抛出异常 if(LoginLimitRefuse.AFTER == LOGIN_PROPERTIES.getLimitRefuse()){ @@ -110,7 +105,9 @@ public class UserTokenUtil { } // 如果是拒绝前者 则弹出前者 else { - redisPlugin.sPop(CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername()); + redisPlugin.sPop( + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()) + ); } } } @@ -135,11 +132,13 @@ public class UserTokenUtil { // 在redis存一份 token 是为了防止 人为造假 // 保存用户token Long saveLong = redisPlugin.sPut( - CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername(), signToken); + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()), + signToken + ); if(saveLong != null && saveLong > 0){ // 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命 redisPlugin.expire( - CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername(), + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()), JwtUtil.EXPIRE_MILLISECOND, TimeUnit.MILLISECONDS); TokenRet tokenRet = new TokenRet(); @@ -249,11 +248,13 @@ public class UserTokenUtil { if(user != null){ // 删除Token信息 redisPlugin.sRemove( - CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername(), token); + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()), + token); // 如果缓存中 无该用户任何Token信息 则删除用户缓存 Long size = redisPlugin.sSize( - CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername()); + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()) + ); if(size == null || size == 0L) { // 删除相关信息 UserUtil.refreshUser(user); @@ -296,7 +297,8 @@ public class UserTokenUtil { String username = getUserNameByToken(token); boolean hashKey = redisPlugin.sHashKey( - CacheUtil.getPrefixName() + TICKET_PREFIX + username, token); + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + username), + token); if(!hashKey){ return false; } @@ -305,7 +307,7 @@ public class UserTokenUtil { if(BooleanUtil.isTrue(LOGIN_PROPERTIES.getReviveMode())){ // 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命 redisPlugin.expire( - CacheUtil.getPrefixName() + TICKET_PREFIX + username, + CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + username), JwtUtil.EXPIRE_MILLISECOND, TimeUnit.MILLISECONDS); } @@ -329,7 +331,7 @@ public class UserTokenUtil { // 判断账号是否临时锁定 Long loseTimeMillis = (Long) redisPlugin.get( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_LOCK_PREFIX + username); + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username)); if(loseTimeMillis != null){ Date currDate = DateUtil.date(); DateTime loseDate = DateUtil.date(loseTimeMillis); @@ -364,18 +366,19 @@ public class UserTokenUtil { // 如果失败次数 超过阈值 则锁定账号 Long slipNum = redisPlugin.increment( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username); + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username)); if (slipNum != null){ // 设置失效时间为 5分钟 redisPlugin.expire( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username, LOGIN_PROPERTIES.getSlipLockSpeed()); + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username), + LOGIN_PROPERTIES.getSlipLockSpeed()); // 如果确认 都失败 则存入临时缓存 if(slipNum >= LOGIN_PROPERTIES.getSlipCount()){ long currentTimeMillis = System.currentTimeMillis(); // 存入Redis redisPlugin.put( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_LOCK_PREFIX + username, + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username), currentTimeMillis, LOGIN_PROPERTIES.getSlipLockSpeed()); } } @@ -396,7 +399,7 @@ public class UserTokenUtil { long count = 0L; Object obj = redisPlugin.get( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username); + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username)); if(obj != null){ try { count = Convert.convert(Long.class, obj); @@ -418,10 +421,10 @@ public class UserTokenUtil { // 删除失败次数记录 redisPlugin.del( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username); + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username)); // 删除失败次数记录 redisPlugin.del( - CacheUtil.getPrefixName() + ACCOUNT_SLIP_LOCK_PREFIX + username); + CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username)); } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java index 9cecacd331118cffec984e43903d6285b38ca02d..f6a833f167e7602cfee047aa5e45db806e933b6c 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java @@ -29,16 +29,18 @@ import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.role.RoleModel; import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel; -import org.opsli.api.wrapper.system.user.UserOrgRefWebModel; +import org.opsli.common.constants.RedisConstants; import org.opsli.common.exception.TokenException; import org.opsli.core.api.TokenThreadLocal; import org.opsli.core.autoconfigure.properties.GlobalProperties; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.cache.SecurityCache; import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.TokenMsg; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.List; @@ -57,16 +59,6 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @Lazy(false) public class UserUtil { - /** 前缀 */ - public static final String PREFIX_ID = "userId:"; - public static final String PREFIX_ID_ROLES = "userId:roles:"; - public static final String PREFIX_ID_DEF_ROLE = "userId:def_role:"; - public static final String PREFIX_ID_ORGS = "userId:orgs:"; - public static final String PREFIX_ID_DEF_ORG = "userId:def_org:"; - public static final String PREFIX_ID_PERMISSIONS = "userId:permissions:"; - public static final String PREFIX_ID_MENUS = "userId:menus:"; - public static final String PREFIX_USERNAME = "username:"; - /** 修改租户权限 */ private static final String PERMS_TENANT = "system_user_tenant"; @@ -85,6 +77,8 @@ public class UserUtil { /** 增加初始状态开关 防止异常使用 */ private static boolean IS_INIT; + private static RedisTemplate redisTemplate; + /** * 获得当前系统登陆用户 * @return UserModel @@ -169,67 +163,24 @@ public class UserUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = PREFIX_ID + userId; - - // 先从缓存里拿 - UserModel userModel = CacheUtil.getTimed(UserModel.class, cacheKey); - if (userModel != null){ - // 如果不是递归触发 可进入一次 - if(!isRecursion){ - // 如果是 切换租户权限 则进行新一轮判断 - // 注意不要陷入递归死循环 只保障循环一次 - if (StringUtils.isNotBlank(userModel.getSwitchTenantUserId())){ - userModel = getUser(userModel.getSwitchTenantUserId(), true); - } - } - return userModel; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - userModel = CacheUtil.getTimed(UserModel.class, cacheKey); - if (userModel != null){ - return userModel; - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + userId); + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 UserModel userModelTemp = new UserModel(); userModelTemp.setId(userId); // 设置为系统内部调用 否则 会拿到 空值 userModelTemp.setIzApi(true); + + // 查询数据库 ResultVo resultVo = userApi.get(userModelTemp); - if(resultVo.isSuccess()){ - userModel = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, userModel); + if(!resultVo.isSuccess()){ + return null; } + return resultVo.getData(); + }, true); - }catch (Exception e){ - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } - - if(userModel == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } + UserModel userModel = Convert.convert(UserModel.class, cache); // 如果不是递归触发 可进入一次 if(!isRecursion){ @@ -255,56 +206,18 @@ public class UserUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = PREFIX_USERNAME + userName; - - // 先从缓存里拿 - UserModel userModel = CacheUtil.getTimed(UserModel.class, cacheKey); - if (userModel != null){ - return userModel; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - userModel = CacheUtil.getTimed(UserModel.class, cacheKey); - if (userModel != null) { - return userModel; - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USERNAME + userName); + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 ResultVo resultVo = userApi.getUserByUsername(userName); - if (resultVo.isSuccess()) { - userModel = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, userModel); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } - - if(userModel == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } + return resultVo.getData(); + }, true); - return userModel; + return Convert.convert(UserModel.class, cache); } /** @@ -325,59 +238,22 @@ public class UserUtil { } // 缓存Key - String cacheKey = PREFIX_ID_ROLES + userId; - - List roles; - - // 先从缓存里拿 - Object obj = CacheUtil.getTimed(cacheKey); - roles = Convert.toList(String.class, obj); - if(CollUtil.isNotEmpty(roles)){ - return roles; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return ListUtil.empty(); - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return ListUtil.empty(); - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - obj = CacheUtil.getTimed(cacheKey); - roles = Convert.toList(String.class, obj); - if(CollUtil.isNotEmpty(roles)){ - return roles; - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_AND_ROLES + userId); + final String finalUserId = userId; + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userRoleRefApi.getRolesByUserId(userId); - if(resultVo.isSuccess()){ - roles = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, roles); + ResultVo> resultVo = userRoleRefApi.getRolesByUserId(finalUserId); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(CollUtil.isEmpty(roles)){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); + List roles = Convert.toList(String.class, cache); + if(null == roles){ return ListUtil.empty(); } - return roles; } @@ -399,60 +275,24 @@ public class UserUtil { userId = currUser.getSwitchTenantUserId(); } - // 缓存Key - String cacheKey = PREFIX_ID_PERMISSIONS + userId; - - List permissions; - // 先从缓存里拿 - Object obj = CacheUtil.getTimed(cacheKey); - permissions = Convert.toList(String.class, obj); - if(CollUtil.isNotEmpty(permissions)){ - return permissions; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return ListUtil.empty(); - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return ListUtil.empty(); - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - obj = CacheUtil.getTimed(cacheKey); - permissions = Convert.toList(String.class, obj); - if(CollUtil.isNotEmpty(permissions)){ - return permissions; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_PERMISSIONS + userId); + final String finalUserId = userId; + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userRoleRefApi.getAllPerms(userId); - if(resultVo.isSuccess()){ - permissions = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, permissions); + ResultVo> resultVo = userRoleRefApi.getAllPerms(finalUserId); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(CollUtil.isEmpty(permissions)){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); + List permissions = Convert.toList(String.class, cache); + if(null == permissions){ return ListUtil.empty(); } - return permissions; } @@ -473,61 +313,24 @@ public class UserUtil { userId = currUser.getSwitchTenantUserId(); } - // 缓存Key - String cacheKey = PREFIX_ID_ORGS + userId; - - List orgList; - - // 先从缓存里拿 - Object obj = CacheUtil.getTimed(cacheKey); - orgList = Convert.toList(UserOrgRefModel.class, obj); - if(CollUtil.isNotEmpty(orgList)){ - return orgList; - } - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return ListUtil.empty(); - } - - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return ListUtil.empty(); - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - obj = CacheUtil.getTimed(cacheKey); - orgList = Convert.toList(UserOrgRefModel.class, obj); - if(CollUtil.isNotEmpty(orgList)){ - return orgList; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_ORGS + userId); + final String finalUserId = userId; + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userOrgRefApi.findListByUserId(userId); - if(resultVo.isSuccess()){ - orgList = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, orgList); + ResultVo> resultVo = userOrgRefApi.findListByUserId(finalUserId); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(CollUtil.isEmpty(orgList)){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); + List orgList = Convert.toList(UserOrgRefModel.class, cache); + if(null == orgList){ return ListUtil.empty(); } - return orgList; } @@ -561,61 +364,24 @@ public class UserUtil { userId = currUser.getSwitchTenantUserId(); } - // 缓存Key - String cacheKey = PREFIX_ID_MENUS + userId; - - List menus; - - // 先从缓存里拿 - Object obj = CacheUtil.getTimed(cacheKey); - menus = Convert.toList(MenuModel.class, obj); - if(CollUtil.isNotEmpty(menus)){ - return menus; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return ListUtil.empty(); - } - - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return ListUtil.empty(); - } - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - obj = CacheUtil.getTimed(cacheKey); - menus = Convert.toList(MenuModel.class, obj); - if(CollUtil.isNotEmpty(menus)){ - return menus; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_MENUS + userId); + final String finalUserId = userId; + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userRoleRefApi.getMenuListByUserId(userId); - if(resultVo.isSuccess()){ - menus = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, menus); + ResultVo> resultVo = userRoleRefApi.getMenuListByUserId(finalUserId); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(CollUtil.isEmpty(menus)){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); + List menus = Convert.toList(MenuModel.class, cache); + if(null == menus){ return ListUtil.empty(); } - return menus; } @@ -637,57 +403,21 @@ public class UserUtil { userId = currUser.getSwitchTenantUserId(); } - // 缓存Key - String cacheKey = PREFIX_ID_DEF_ROLE + userId; - - // 先从缓存里拿 - RoleModel roleModel = CacheUtil.getTimed(RoleModel.class, cacheKey); - if (roleModel != null){ - return roleModel; - } - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - roleModel = CacheUtil.getTimed(RoleModel.class, cacheKey); - if (roleModel != null){ - return roleModel; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ROLE + userId); + final String finalUserId = userId; + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = userRoleRefApi.getDefRoleByUserId(userId); - if(resultVo.isSuccess()){ - roleModel = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, roleModel); + ResultVo resultVo = userRoleRefApi.getDefRoleByUserId(finalUserId); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(roleModel == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } - - return roleModel; + return Convert.convert(RoleModel.class, cache); } @@ -710,56 +440,19 @@ public class UserUtil { } // 缓存Key - String cacheKey = PREFIX_ID_DEF_ORG + userId; - - // 先从缓存里拿 - UserOrgRefModel orgModel = CacheUtil.getTimed(UserOrgRefModel.class, cacheKey); - if (orgModel != null){ - return orgModel; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - orgModel = CacheUtil.getTimed(UserOrgRefModel.class, cacheKey); - if (orgModel != null){ - return orgModel; - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ORG + userId); + final String finalUserId = userId; + Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = userOrgRefApi.getDefOrgByUserId(userId); - if(resultVo.isSuccess()){ - orgModel = resultVo.getData(); - // 存入缓存 - CacheUtil.put(cacheKey, orgModel); + ResultVo resultVo = userOrgRefApi.getDefOrgByUserId(finalUserId); + if(!resultVo.isSuccess()){ + return null; } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + return resultVo.getData(); + }, true); - if(orgModel == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } - - return orgModel; + return Convert.convert(UserOrgRefModel.class, cache); } @@ -781,33 +474,11 @@ public class UserUtil { } // 缓存Key - String cacheKey = PREFIX_ID + user.getId(); - try { - // 存入缓存 - CacheUtil.put(cacheKey, user); - }catch (Exception e){ - log.error(e.getMessage(), e); - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return false; - } - - // 存入缓存 - flag = CacheUtil.put(cacheKey, user); - }catch (Exception e){ - flag = false; - log.error(e.getMessage(), e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + user.getId()); + // 存入缓存 + SecurityCache.put(redisTemplate, cacheKey, user); - return flag; + return true; } /** @@ -824,55 +495,11 @@ public class UserUtil { return true; } - UserModel userModelById = CacheUtil.getTimed( - UserModel.class, PREFIX_ID + user.getId()); - UserModel userModelByUsername = CacheUtil.getTimed( - UserModel.class, PREFIX_USERNAME + user.getUsername()); - - boolean hasNilFlagById = CacheUtil.hasNilFlag(PREFIX_ID + user.getId()); - boolean hasNilFlagByName = CacheUtil.hasNilFlag(PREFIX_USERNAME + user.getUsername()); - - // 计数器 - int count = 0; - - if (hasNilFlagById){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID + user.getId()); - if(tmp){ - count--; - } - } - - if (hasNilFlagByName){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_USERNAME + user.getUsername()); - if(tmp){ - count--; - } - } - - // 只要有一个不为空 则执行刷新 - if (userModelById != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID + user.getId()); - if(tmp){ - count--; - } - } + String cacheKeyByUserId = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + user.getId()); + String cacheKeyByUsername = CacheUtil.formatKey(RedisConstants.PREFIX_USERNAME + user.getUsername()); - if (userModelByUsername != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_USERNAME + user.getUsername()); - if(tmp){ - count--; - } - } - - return count == 0; + return SecurityCache.removeMore(redisTemplate, + cacheKeyByUserId, cacheKeyByUsername); } @@ -886,32 +513,9 @@ public class UserUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - Object obj = CacheUtil.getTimed(PREFIX_ID_ROLES + userId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_ROLES + userId); - - // 计数器 - int count = 0; - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_ROLES + userId); - if(tmp){ - count--; - } - } - - if(obj != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID_ROLES + userId); - if(tmp){ - count--; - } - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_AND_ROLES + userId); - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } /** @@ -928,32 +532,9 @@ public class UserUtil { return true; } - // 计数器 - int count = 0; - - RoleModel roleModel = CacheUtil.getTimed(RoleModel.class, PREFIX_ID_DEF_ROLE + userId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_DEF_ROLE + userId); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_DEF_ROLE + userId); - if(tmp){ - count--; - } - } - - if(roleModel != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID_DEF_ROLE + userId); - if(tmp){ - count--; - } - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ROLE + userId); - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } @@ -968,34 +549,9 @@ public class UserUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_PERMISSIONS + userId); - Object obj = CacheUtil.getTimed(PREFIX_ID_PERMISSIONS + userId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_PERMISSIONS + userId); - - // 计数器 - int count = 0; - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_PERMISSIONS + userId); - if(tmp){ - count--; - } - } - - if(obj != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID_PERMISSIONS + userId); - if(tmp){ - count--; - } - } - - - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } /** @@ -1012,31 +568,9 @@ public class UserUtil { return true; } - // 计数器 - int count = 0; + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_ORGS + userId); - UserOrgRefWebModel orgRefModel = CacheUtil.getTimed(UserOrgRefWebModel.class, PREFIX_ID_ORGS + userId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_ORGS + userId); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_ORGS + userId); - if(tmp){ - count--; - } - } - - if(orgRefModel != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID_ORGS + userId); - if(tmp){ - count--; - } - } - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } /** @@ -1053,32 +587,9 @@ public class UserUtil { return true; } - // 计数器 - int count = 0; - - UserOrgRefModel orgModel = CacheUtil.getTimed(UserOrgRefModel.class, PREFIX_ID_DEF_ORG + userId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_DEF_ORG + userId); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_DEF_ORG + userId); - if(tmp){ - count--; - } - } - - if(orgModel != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID_DEF_ORG + userId); - if(tmp){ - count--; - } - } + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ORG + userId); - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } @@ -1092,33 +603,9 @@ public class UserUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_MENUS + userId); - Object obj = CacheUtil.getTimed(PREFIX_ID_MENUS + userId); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_MENUS + userId); - - // 计数器 - int count = 0; - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_MENUS + userId); - if(tmp){ - count--; - } - } - - if(obj != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_ID_MENUS + userId); - if(tmp){ - count--; - } - } - - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } /** @@ -1201,7 +688,8 @@ public class UserUtil { public void init(GlobalProperties globalProperties, UserApi userApi, UserRoleRefApi userRoleRefApi, - UserOrgRefApi userOrgRefApi){ + UserOrgRefApi userOrgRefApi, + RedisTemplate redisTemplate) { if(globalProperties != null && globalProperties.getAuth() != null && globalProperties.getAuth().getToken() != null ){ @@ -1210,11 +698,9 @@ public class UserUtil { } UserUtil.userApi = userApi; - UserUtil.userRoleRefApi = userRoleRefApi; - UserUtil.userOrgRefApi = userOrgRefApi; - + UserUtil.redisTemplate = redisTemplate; IS_INIT = true; } diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/web/GenLogsRestController.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/web/GenLogsRestController.java index 70600b4fb081e2223f6308f86027aca8047c6a9f..103ed3378e4917aa3eefa5c6c4d1ddb68d50fbb5 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/web/GenLogsRestController.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/web/GenLogsRestController.java @@ -40,7 +40,7 @@ import javax.servlet.http.HttpServletResponse; */ @Api(tags = GenLogsApi.TITLE) @Slf4j -@ApiRestController("/generator/logs/{ver}") +@ApiRestController("/{ver}/generator/logs") public class GenLogsRestController extends BaseRestController implements GenLogsApi { diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/table/web/GenTableRestController.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/table/web/GenTableRestController.java index 7457aa083842823c5cd884c21dcce085c5ca74d1..b071d0451533350d0deb49f4025454e9237e2377 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/table/web/GenTableRestController.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/table/web/GenTableRestController.java @@ -57,7 +57,7 @@ import java.util.Map; */ @Api(tags = TableApi.TITLE) @Slf4j -@ApiRestController("/generator/table/{ver}") +@ApiRestController("/{ver}/generator/table") public class GenTableRestController extends BaseRestController implements TableApi { diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateDetailRestController.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateDetailRestController.java index 5c98c5d061c752a328215b619b6584dc5bce3807..1c669633de84a8f0b506a7c39e3b375745f4e7d4 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateDetailRestController.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateDetailRestController.java @@ -54,7 +54,7 @@ import org.opsli.modulars.generator.template.service.IGenTemplateDetailService; */ @Api(tags = GenTemplateDetailRestApi.TITLE) @Slf4j -@ApiRestController("/generator/template/detail/{ver}") +@ApiRestController("/{ver}/generator/template/detail") public class GenTemplateDetailRestController extends BaseRestController implements GenTemplateDetailRestApi { diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateRestController.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateRestController.java index a0a97a0c85d617839924e40f56b287b6e9cd4247..1f3bab90799121d404c692a484963d295207828b 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateRestController.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/web/GenTemplateRestController.java @@ -53,7 +53,7 @@ import org.opsli.modulars.generator.template.service.IGenTemplateService; */ @Api(tags = GenTemplateRestApi.TITLE) @Slf4j -@ApiRestController("/generator/template/{ver}") +@ApiRestController("/{ver}/generator/template/") public class GenTemplateRestController extends BaseRestController implements GenTemplateRestApi { diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java index 4e54857eda94fd5a7f4f779aeaeca96a4291b41c..7868f839c7ed769bf54939b9fbb31d7d467ada7a 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java @@ -20,23 +20,18 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.comparator.CompareUtil; import cn.hutool.core.convert.Convert; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.opsli.api.base.result.ResultVo; -import org.opsli.api.web.system.dict.DictDetailApi; -import org.opsli.api.wrapper.system.dict.DictDetailModel; -import org.opsli.api.wrapper.system.dict.DictWrapper; -import org.opsli.common.constants.DictConstants; -import org.opsli.core.cache.local.CacheUtil; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.cache.SecurityCache; import org.opsli.core.msg.CoreMsg; -import org.opsli.core.utils.DictUtil; -import org.opsli.core.utils.DistributedLockUtil; import org.opsli.core.utils.ThrowExceptionUtil; import org.opsli.modulars.generator.template.service.IGenTemplateDetailService; import org.opsli.modulars.generator.template.wrapper.GenTemplateDetailModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.List; @@ -60,11 +55,13 @@ public class GenTemplateUtil { private static boolean IS_INIT; /** 缓存前缀 NAME */ - private static final String CACHE_PREFIX_NAME = "gen:template:"; + private static final String CACHE_PREFIX_NAME = "hash#{}:gen:template:"; /** 代码模板明细 Service */ private static IGenTemplateDetailService genTemplateDetailService; + private static RedisTemplate redisTemplate; + /** * 根据模板ID 模板明细列表 * @param parentId 模板ID @@ -76,77 +73,21 @@ public class GenTemplateUtil { CoreMsg.OTHER_EXCEPTION_UTILS_INIT); // 缓存Key - String cacheKey = CACHE_PREFIX_NAME + parentId; - - // 处理集合数据 - List wrapperModels = handleDictList( - CacheUtil.getHashAll(cacheKey), parentId); - if(CollUtil.isNotEmpty(wrapperModels)){ - return sortWrappers(wrapperModels); - } - - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return sortWrappers(wrapperModels); - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return sortWrappers(wrapperModels); - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - // 处理集合数据 - wrapperModels = handleDictList( - CacheUtil.getHashAll(cacheKey), parentId); - if(CollUtil.isNotEmpty(wrapperModels)){ - return sortWrappers(wrapperModels); - } - + String cacheKey = CacheUtil.formatKey(CACHE_PREFIX_NAME + parentId); - List listByParent = genTemplateDetailService.findListByParent(parentId); + Map templateCache = SecurityCache.hGetAll(redisTemplate, cacheKey, (k) -> { // 处理数据库查询数据 - if(CollUtil.isNotEmpty(listByParent)){ - wrapperModels = listByParent; - // 计数器 - int count = wrapperModels.size(); - for (GenTemplateDetailModel model : wrapperModels) { - // 保存至缓存 - boolean ret = GenTemplateUtil.put(model); - if(ret){ - count--; - } - } - - // 回滚 清空缓存 - if(count != 0){ - for (GenTemplateDetailModel model : wrapperModels) { - GenTemplateUtil.del(model); - } - } - - return sortWrappers(wrapperModels); + List listByParent = genTemplateDetailService.findListByParent(parentId); + Map templateMap = Maps.newHashMapWithExpectedSize(listByParent.size()); + for (GenTemplateDetailModel genTemplateDetailModel : listByParent) { + templateMap.put(genTemplateDetailModel.getId(), genTemplateDetailModel); } + return templateMap; + }); - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } - - // 如果值还是 为空 则赋默认值 - if(CollUtil.isEmpty(wrapperModels)){ - // 加入缓存防穿透 - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - } - // 排序 + // 处理集合数据 + List wrapperModels = handleDictList(templateCache); return sortWrappers(wrapperModels); } @@ -157,8 +98,8 @@ public class GenTemplateUtil { */ private static List sortWrappers(List wrapperModels) { // 非法判读 - if(wrapperModels == null){ - return null; + if(CollUtil.isEmpty(wrapperModels)){ + return ListUtil.empty(); } return ListUtil.sort(wrapperModels, @@ -169,22 +110,6 @@ public class GenTemplateUtil { // =============== - /** - * 删除 字典 - * @param model 字典模型 - */ - private static boolean put(GenTemplateDetailModel model){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 清除缓存 - GenTemplateUtil.del(model); - - return CacheUtil.putHash(CACHE_PREFIX_NAME + model.getParentId(), - model.getId(), model); - } - /** * 删除 字典 * @param model 字典模型 @@ -199,36 +124,10 @@ public class GenTemplateUtil { return true; } - boolean hasNilFlag = CacheUtil.hasNilFlag(CACHE_PREFIX_NAME + - model.getParentId() + ":" + model.getId()); - - GenTemplateDetailModel templateDetailModel = CacheUtil.getHash(GenTemplateDetailModel.class, - CACHE_PREFIX_NAME + model.getParentId(), - model.getId()); - - // 计数器 - int count = 0; - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(CACHE_PREFIX_NAME + - model.getParentId() + ":" + model.getId()); - if(tmp){ - count--; - } - } - - if (templateDetailModel != null){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delHash(CACHE_PREFIX_NAME + - model.getParentId(), model.getId()); - if(tmp){ - count--; - } - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(CACHE_PREFIX_NAME + model.getParentId()); - return count == 0; + return SecurityCache.hDel(redisTemplate, cacheKey, model.getId()); } /** @@ -241,29 +140,18 @@ public class GenTemplateUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - List wrapperList = GenTemplateUtil.getTemplateDetailList(parentId); - if(CollUtil.isEmpty(wrapperList)){ - return true; - } + // 缓存Key + String cacheKey = CacheUtil.formatKey(CACHE_PREFIX_NAME + parentId); - // 计数器 - int count = wrapperList.size(); - for (GenTemplateDetailModel wrapperModel : wrapperList) { - boolean tmp = GenTemplateUtil.del(wrapperModel); - if(tmp){ - count--; - } - } - return count == 0; + return SecurityCache.remove(redisTemplate, cacheKey); } /*** * 处理返回模板明细集合 * @param tempMap Map - * @param id 模板ID * @return List */ - public static List handleDictList(Map tempMap, String id){ + public static List handleDictList(Map tempMap){ List wrapperModels = Lists.newArrayList(); if(CollUtil.isNotEmpty(tempMap)){ for (Map.Entry entry : tempMap.entrySet()) { @@ -285,8 +173,10 @@ public class GenTemplateUtil { * 初始化 */ @Autowired - public void init(IGenTemplateDetailService genTemplateDetailService) { + public void init(IGenTemplateDetailService genTemplateDetailService, + RedisTemplate redisTemplate) { GenTemplateUtil.genTemplateDetailService = genTemplateDetailService; + GenTemplateUtil.redisTemplate = redisTemplate; IS_INIT = true; } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/area/web/SysAreaRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/area/web/SysAreaRestController.java index 8a8db0808c17338dba2f7af00af7a7db6b091f8e..05b0842b5a4cf3f7b9ae98e2dfb0e8ce29205127 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/area/web/SysAreaRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/area/web/SysAreaRestController.java @@ -71,7 +71,7 @@ import java.util.Set; */ @Api(tags = SysAreaRestApi.TITLE) @Slf4j -@ApiRestController("/system/area/{ver}") +@ApiRestController("/{ver}/system/area") public class SysAreaRestController extends BaseRestController implements SysAreaRestApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictDetailRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictDetailRestController.java index e03be5d2927a3ebc9346abf696116f62e3a8d2dd..1e535a06feede629f629cb8fc6a38af455788343 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictDetailRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictDetailRestController.java @@ -56,7 +56,7 @@ import java.util.List; */ @Api(tags = DictDetailApi.TITLE) @Slf4j -@ApiRestController("/system/dict/detail/{ver}") +@ApiRestController("/{ver}/system/dict/detail") public class DictDetailRestController extends BaseRestController implements DictDetailApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictRestController.java index 1c31645c68807c8a5cc23c6a9dbbd01d89023f8a..e4f2e3dc001bbf10a6f47f8c78f43985190b33f7 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/dict/web/DictRestController.java @@ -59,7 +59,7 @@ import java.util.List; */ @Api(tags = DictApi.TITLE) @Slf4j -@ApiRestController("/system/dict/{ver}") +@ApiRestController("/{ver}/system/dict") public class DictRestController extends BaseRestController implements DictApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java index ae3166816a596ddc9b98992009e458962c913927..c149e02613e8baebb4dce6b28444133406cbfe2f 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java @@ -26,7 +26,7 @@ import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.api.wrapper.system.tenant.TenantModel; import org.opsli.api.wrapper.system.user.UserModel; -import org.opsli.common.annotation.ApiCryptoAsymmetric; +import org.opsli.common.annotation.LoginCrypto; import org.opsli.common.annotation.Limiter; import org.opsli.common.enums.DictType; import org.opsli.common.thread.AsyncProcessExecutor; @@ -73,7 +73,7 @@ public class LoginRestController { * 登录 登录数据加密 */ @Limiter - @ApiCryptoAsymmetric(responseEncrypt = false) + @LoginCrypto @ApiOperation(value = "登录", notes = "登录") @PostMapping("/system/login") public ResultVo login(@RequestBody LoginForm form, HttpServletRequest request){ diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LogsRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LogsRestController.java index db888ccb34beb12f5e134ce7bdbf5bd44715ae39..893807e29d217bcce8678dcd5319f3dee380e32c 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LogsRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LogsRestController.java @@ -42,7 +42,7 @@ import javax.servlet.http.HttpServletRequest; */ @Api(tags = LogsApi.TITLE) @Slf4j -@ApiRestController("/system/logs/{ver}") +@ApiRestController("/{ver}/system/logs") public class LogsRestController extends BaseRestController implements LogsApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java index d02b6116bfd216c7554c6b88e1cf2ac8c2bb85dc..044700fa9125455e2d5e3b5e2b7d2e7f3039dbfe 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java @@ -73,7 +73,7 @@ import java.util.Map; */ @Api(tags = MenuApi.TITLE) @Slf4j -@ApiRestController("/system/menu/{ver}") +@ApiRestController("/{ver}/system/menu") public class MenuRestController extends BaseRestController implements MenuApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/monitor/web/MonitorController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/monitor/web/MonitorController.java index e3c4469d90cc521b321b1aa830c05494975ad2b9..b7017907456d8b97923d2c255bdc174c5436fe90 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/monitor/web/MonitorController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/monitor/web/MonitorController.java @@ -35,7 +35,7 @@ import java.util.Map; */ @Api(tags = "系统监控") @Slf4j -@ApiRestController("/system/monitor/{ver}") +@ApiRestController("/{ver}/system/monitor") public class MonitorController { /** diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java index 2582d2a3e26436e8978a233df451ab2563a4aed7..28bdcb0979d74959d012827540c3df5b5743bdc0 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java @@ -60,7 +60,7 @@ import java.util.Map; */ @Api(tags = OptionsApi.TITLE) @Slf4j -@ApiRestController("/system/options/{ver}") +@ApiRestController("/{ver}/system/options") public class SysOptionsRestController extends BaseRestController implements OptionsApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/web/SysOrgRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/web/SysOrgRestController.java index 9443ca817c1e85b72ebc009052920a75cc76b4e5..2b8f78dc920915a836cd7ff312c07e965bb4064c 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/web/SysOrgRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/web/SysOrgRestController.java @@ -73,7 +73,7 @@ import java.util.Set; */ @Api(tags = SysOrgRestApi.TITLE) @Slf4j -@ApiRestController("/system/org/{ver}") +@ApiRestController("/{ver}/system/org") public class SysOrgRestController extends BaseRestController implements SysOrgRestApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleMenuRefRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleMenuRefRestController.java index cfac125899c43bda4c053798911badbf41a9a635..8a7a214660353e0dd71697458f7ed52a87baf99a 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleMenuRefRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleMenuRefRestController.java @@ -48,7 +48,7 @@ import java.util.stream.Collectors; */ @Api(tags = RoleMenuRefApi.TITLE) @Slf4j -@ApiRestController("/system/role/perms/{ver}") +@ApiRestController("/{ver}/system/role/perms") public class RoleMenuRefRestController implements RoleMenuRefApi { /** 配置类 */ diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleRestController.java index 95c82e741643412140b67e18884a7201364bc0a4..d89586d67f6e12b28c137e857cfe12302ac559e4 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/web/RoleRestController.java @@ -49,7 +49,7 @@ import java.lang.reflect.Method; */ @Api(tags = "角色管理") @Slf4j -@ApiRestController("/system/role/{ver}") +@ApiRestController("/{ver}/system/role") public class RoleRestController extends BaseRestController implements RoleApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/web/TenantRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/web/TenantRestController.java index e1874c643c4dacbcc9b1dc01c87a78fb1bfc90cc..a16c203ebd399dc44805a63207b91e5d36c4932a 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/web/TenantRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/web/TenantRestController.java @@ -52,7 +52,7 @@ import java.lang.reflect.Method; */ @Api(tags = TenantApi.TITLE) @Slf4j -@ApiRestController("/system/tenant/{ver}") +@ApiRestController("/{ver}/system/tenant") public class TenantRestController extends BaseRestController implements TenantApi { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserOrgRefRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserOrgRefRestController.java index f262230f538b920f54f67420a68bc9599b3eba08..5e051bb03e787b14cd0b85e0d2e3ddd7cc88f85c 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserOrgRefRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserOrgRefRestController.java @@ -54,7 +54,7 @@ import java.util.List; */ @Api(tags = UserOrgRefApi.TITLE) @Slf4j -@ApiRestController("/system/user/org/{ver}") +@ApiRestController("/{ver}/system/user/org") public class UserOrgRefRestController implements UserOrgRefApi { /** 配置类 */ diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserRestController.java index 9af3803a6fcddc2f9c4257ab50b0a85572f317a2..7aa9ddeafb0226b62ed8b5e96d0a8fd7d52b7918 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/web/UserRestController.java @@ -17,6 +17,7 @@ package org.opsli.modulars.system.user.web; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.excel.util.CollectionUtils; @@ -61,6 +62,7 @@ import org.opsli.plugins.oss.OssStorageFactory; import org.opsli.plugins.oss.service.BaseOssStorageService; import org.opsli.plugins.oss.service.OssStorageService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -80,7 +82,7 @@ import java.util.List; */ @Api(tags = UserApi.TITLE) @Slf4j -@ApiRestController("/system/user/{ver}") +@ApiRestController("/{ver}/system/user") public class UserRestController extends BaseRestController implements UserApi { @@ -215,10 +217,14 @@ public class UserRestController extends BaseRestController implements TestCarRestApi { diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/user/web/TestUserRestController.java b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/user/web/TestUserRestController.java index 695c82936bd3d1e26992d588ca3bb0283820aceb..f837012bad452a2c74f847040fdb549b66230a74 100644 --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/user/web/TestUserRestController.java +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/user/web/TestUserRestController.java @@ -48,7 +48,7 @@ import java.lang.reflect.Method; */ @Api(tags = TestUserRestApi.TITLE) @Slf4j -@ApiRestController("/gentest/user/{ver}") +@ApiRestController("/{ver}/gentest/user") public class TestUserRestController extends BaseRestController implements TestUserRestApi { diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/test/web/TestRestController.java b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/test/web/TestRestController.java index e417dd694588354ffd413c9f09374af720e224d0..c0ecaf9d83d372b9c49933d782fb493f3581955d 100644 --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/test/web/TestRestController.java +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/test/web/TestRestController.java @@ -32,7 +32,7 @@ import java.lang.reflect.Method; */ @Api(tags = "测试类") @Slf4j -@ApiRestController("/test/{ver}") +@ApiRestController("/{ver}/test") public class TestRestController extends BaseRestController implements TestRestApi { diff --git a/opsli-plugins/opsli-plugins-crypto/src/main/java/opsli/plugins/crypto/strategy/impl/CryptoSymmetricServiceImpl.java b/opsli-plugins/opsli-plugins-crypto/src/main/java/opsli/plugins/crypto/strategy/impl/CryptoSymmetricServiceImpl.java index 54f561597f09ecaad458032d9f0ca2f95180e253..cadef75aee30e985a9ca115d04817f387290b1a8 100644 --- a/opsli-plugins/opsli-plugins-crypto/src/main/java/opsli/plugins/crypto/strategy/impl/CryptoSymmetricServiceImpl.java +++ b/opsli-plugins/opsli-plugins-crypto/src/main/java/opsli/plugins/crypto/strategy/impl/CryptoSymmetricServiceImpl.java @@ -18,8 +18,12 @@ package opsli.plugins.crypto.strategy.impl; import cn.hutool.core.codec.Base64; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.Mode; +import cn.hutool.crypto.Padding; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SmUtil; +import cn.hutool.crypto.symmetric.AES; +import cn.hutool.crypto.symmetric.DES; import cn.hutool.crypto.symmetric.SymmetricCrypto; import cn.hutool.json.JSONException; import cn.hutool.json.JSONUtil; @@ -245,11 +249,11 @@ public class CryptoSymmetricServiceImpl implements CryptoSymmetricService { byte[] keyBytes = Base64.decode(model.getPrivateKey()); switch (model.getCryptoType()) { case AES:{ - tmp = SecureUtil.aes(keyBytes); + tmp = new AES(Mode.ECB, Padding.PKCS5Padding, keyBytes); break; } case DES:{ - tmp = SecureUtil.des(keyBytes); + tmp = new DES(Mode.ECB, Padding.PKCS5Padding, keyBytes); break; } case DE_SEDE:{ diff --git a/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json index e02ef412348804b097608d12c57279cda56e360f..6e73d4f43f352b7b7f67cd24bbcae4aae4429041 100644 --- a/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,10 +1,4 @@ { "properties": [ - { - "name": "spring.redis.pushsub.enable", - "type": "java.lang.Boolean", - "defaultValue": false, - "description": "开启消息订阅." - } ] } diff --git a/opsli-starter/pom.xml b/opsli-starter/pom.xml index 7f4ee79d162af144de21f38b90f868d8b07b3eb9..fb96bc686ecfde9dc196056d7f909da1df9837f6 100644 --- a/opsli-starter/pom.xml +++ b/opsli-starter/pom.xml @@ -11,7 +11,7 @@ 4.0.0 opsli-starter - 1.6.0 + 1.6.2 diff --git a/opsli-starter/src/main/resources/application.yaml b/opsli-starter/src/main/resources/application.yaml index 21990b94522ce1393f97e1f9b710bfcd920fda62..44d7769d7d0fd6334a4fac4e1bbc5eba1e21bbd7 100644 --- a/opsli-starter/src/main/resources/application.yaml +++ b/opsli-starter/src/main/resources/application.yaml @@ -54,21 +54,11 @@ spring: # allow-bean-definition-overriding: true # 缓存配置项 - cache-conf: + cache: # 前缀 prefix: opsli - # 一级缓存 ---- EhCache 配置 - cache: - # 是否启用本地缓存 (默认不启用, 如果业务对于缓存依赖较高可启用本地缓存作为一级缓存) - enable: false - # 加载配置文件 - jcache: - config: classpath:config/ehcache-opsli.xml # 二级缓存 ---- Redis 配置 redis: - # 开启消息订阅 - pushsub: - enable: true lettuce: pool: max-active: 8 #最大连接数据库连接数,设 0 为没有限制 @@ -163,8 +153,8 @@ opsli: url-patterns: "/*" # 排除过滤URL url-exclusion: - - "/api/generator/template/v1/insertAndDetail" - - "/api/generator/template/v1/updateAndDetail" + - "/api/v1/generator/template/insertAndDetail" + - "/api/v1/generator/template/updateAndDetail" - "/static/files/" - "/doc.html" diff --git a/opsli-starter/src/main/resources/config/ehcache-opsli.xml b/opsli-starter/src/main/resources/config/ehcache-opsli.xml deleted file mode 100644 index f288899270bf93f97ac11e3f313b5df7ce153275..0000000000000000000000000000000000000000 --- a/opsli-starter/src/main/resources/config/ehcache-opsli.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - java.lang.String - java.lang.Object - - 2000 - - - - - - - - - - 21600 - - - - \ No newline at end of file diff --git a/push.bat b/push.bat index c6e3b7f6273bd4fad9a3b82cc1e4653591bef179..2418a3f4c3b55ce69b53a0c426412f19bc6fe1cf 100644 --- a/push.bat +++ b/push.bat @@ -2,8 +2,8 @@ echo "Git Pushing ......" echo "" -git push "git@github.com:hiparker/opsli-boot.git" master -git push -f "git@gitee.com:hiparker/opsli-boot.git" master +git push "git@github.com:hiparker/opsli-boot.git" development +git push -f "git@gitee.com:hiparker/opsli-boot.git" development diff --git a/push.sh b/push.sh index bc3f7d87f846bb752d1d3f655f4de067d0a1fd55..fdcc1e44476ab94debf86b11acf35aa3653f544c 100755 --- a/push.sh +++ b/push.sh @@ -2,8 +2,8 @@ echo "Git Pushing ......" echo "" -git push "git@github.com:hiparker/opsli-boot.git" master -git push -f "git@gitee.com:hiparker/opsli-boot.git" master +git push "git@github.com:hiparker/opsli-boot.git" development +git push -f "git@gitee.com:hiparker/opsli-boot.git" development