diff --git a/LICENSE b/LICENSE index 261eeb9..a25dade 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + 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. diff --git a/db-file/Dockerfile b/db-file/1.x版本/Dockerfile similarity index 100% rename from db-file/Dockerfile rename to db-file/1.x版本/Dockerfile diff --git a/db-file/opsli-boot.sql b/db-file/1.x版本/opsli-boot.sql similarity index 98% rename from db-file/opsli-boot.sql rename to db-file/1.x版本/opsli-boot.sql index 270536d..0c4f216 100644 --- a/db-file/opsli-boot.sql +++ b/db-file/1.x版本/opsli-boot.sql @@ -226,7 +226,7 @@ INSERT INTO `gen_template_detail` VALUES (1469919953401061378, 13982537047248281 INSERT INTO `gen_template_detail` VALUES (1469919953589805058, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); INSERT INTO `gen_template_detail` VALUES (1469919953728217090, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); INSERT INTO `gen_template_detail` VALUES (1469919953849851905, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); -INSERT INTO `gen_template_detail` VALUES (1469919954038595585, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); +INSERT INTO `gen_template_detail` VALUES (1469919954038595585, 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<>(IService.getEntityClass(), 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<>(IService.getEntityClass(), 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); INSERT INTO `gen_template_detail` VALUES (1469919954235727874, 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02'); INSERT INTO `gen_template_detail` VALUES (1469919954428665858, 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02'); INSERT INTO `gen_template_detail` VALUES (1469919954567077890, 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02'); @@ -3926,8 +3926,8 @@ 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', '0', NULL); 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', '0', NULL); 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', '0', NULL); -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', '0', NULL); -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', '0', NULL); +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<>(IService.getEntityClass(), 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<>(IService.getEntityClass(), 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', '0', NULL); +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<>(IService.getEntityClass(), 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<>(IService.getEntityClass(), 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', '0', NULL); 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', '0', NULL); 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', '0', NULL); 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', '0', NULL); @@ -3960,7 +3960,7 @@ INSERT INTO `sys_logs` VALUES (1465998771136114690, '2', '测试模块-汽车信 INSERT INTO `sys_logs` VALUES (1465999901954027521, '1', '测试模块-汽车信息-新增', '', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0', '/opsli-boot/api/gentest/carinfo/v1/insert', 'POST', 232, '[{\"carBrand\":\"测试汽车\",\"carName\":\"测试汽车\",\"izUsable\":\"1\",\"izApi\":false,\"version\":0,\"carType\":\"测试汽车\",\"izManual\":false,\"produceData\":1638288000000}]', NULL, 0, 1465879900211294210, '2021-12-01 19:03:08', 1465879900211294210, '2021-12-01 19:03:08', '2021-12-01 19:00:54', '0', NULL); INSERT INTO `sys_logs` VALUES (1469909572632846337, '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/v1/system/user/enableAccount', 'POST', 134, '[\"1315218541317750785\",\"0\"]', NULL, 0, 1465879900211294210, '2021-12-12 13:58:46', 1465879900211294210, '2021-12-12 13:58:46', '2021-12-12 13:56:47', '0', NULL); INSERT INTO `sys_logs` VALUES (1469909576810373121, '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/v1/system/user/enableAccount', 'POST', 124, '[\"1315218541317750785\",\"1\"]', NULL, 0, 1465879900211294210, '2021-12-12 13:58:47', 1465879900211294210, '2021-12-12 13:58:47', '2021-12-12 13:56:48', '0', NULL); -INSERT INTO `sys_logs` VALUES (1469919956693590018, '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/v1/generator/template/updateAndDetail', 'POST', 878, '[{\"izApi\":false,\"remark\":\"默认Form表单\",\"updateTime\":1638267134000,\"version\":33,\"tableType\":\"0\",\"tempName\":\"Form表单\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1622204636000,\"updateBy\":\"1465171199435362305\",\"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(\\\"/{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}\"},{\"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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02', '2021-12-12 14:38:02', '0', NULL); +INSERT INTO `sys_logs` VALUES (1469919956693590018, '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/v1/generator/template/updateAndDetail', 'POST', 878, '[{\"izApi\":false,\"remark\":\"默认Form表单\",\"updateTime\":1638267134000,\"version\":33,\"tableType\":\"0\",\"tempName\":\"Form表单\",\"createBy\":\"1313694379541635074\",\"izManual\":false,\"createTime\":1622204636000,\"updateBy\":\"1465171199435362305\",\"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(\\\"/{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<>(IService.getEntityClass(), 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<>(IService.getEntityClass(), 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02', '2021-12-12 14:38:02', '0', NULL); INSERT INTO `sys_logs` VALUES (1504319857552412673, '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/v1/system/options/insert', 'POST', 230, '[{\"izApi\":false,\"version\":0,\"izLock\":\"0\",\"izManual\":false,\"optionCode\":\"123321\",\"optionName\":\"123132\"}]', NULL, 0, 1465171199435362305, '2022-03-17 12:52:58', 1465171199435362305, '2022-03-17 12:52:58', '2022-03-17 12:53:07', '0', NULL); INSERT INTO `sys_logs` VALUES (1504320213128728577, '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/v1/system/options/update', 'POST', 18716, '[{\"izApi\":false,\"version\":0,\"createBy\":\"1465171199435362305\",\"izLock\":\"0\",\"izManual\":false,\"createTime\":1647492777000,\"id\":\"1504319856055046145\",\"optionName\":\"123132\"}]', NULL, 0, 1465171199435362305, '2022-03-17 12:54:22', 1465171199435362305, '2022-03-17 12:54:22', '2022-03-17 12:54:32', '0', NULL); INSERT INTO `sys_logs` VALUES (1504320746870677505, '2', '系统配置-系统设置-更新', '', '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/v1/system/options/update', 'POST', 436, '[{\"izApi\":false,\"version\":0,\"createBy\":\"1465171199435362305\",\"izLock\":\"0\",\"izManual\":false,\"createTime\":1647492777000,\"id\":\"1504319856055046145\",\"optionName\":\"123132\"}]', '更新数据失败,是否刷新页面重试?', 0, 1465171199435362305, '2022-03-17 12:56:30', 1465171199435362305, '2022-03-17 12:56:30', '2022-03-17 12:56:39', '0', NULL); diff --git a/db-file/升级SQL/1.6.2 =》1.6.3 .sql b/db-file/1.x版本/升级SQL/1.6.2 =》1.6.3 .sql similarity index 81% rename from db-file/升级SQL/1.6.2 =》1.6.3 .sql rename to db-file/1.x版本/升级SQL/1.6.2 =》1.6.3 .sql index 9014a08..ba24f63 100644 --- a/db-file/升级SQL/1.6.2 =》1.6.3 .sql +++ b/db-file/1.x版本/升级SQL/1.6.2 =》1.6.3 .sql @@ -25,8 +25,8 @@ INSERT INTO `gen_template_detail` VALUES (1469919953178763265, 13982537047248281 INSERT INTO `gen_template_detail` VALUES (1469919953401061378, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/mapper', '${model.tableHumpName}Mapper.java', '#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}', '0', 0, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); INSERT INTO `gen_template_detail` VALUES (1469919953589805058, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); INSERT INTO `gen_template_detail` VALUES (1469919953728217090, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); -INSERT INTO `gen_template_detail` VALUES (1469919953849851905, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); -INSERT INTO `gen_template_detail` VALUES (1469919954038595585, 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); +INSERT INTO `gen_template_detail` VALUES (1469919953849851905, 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 ResultWrapper\n */\n @GetMapping(\"/get\")\n ResultWrapper<#(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 ResultWrapper\n */\n @GetMapping(\"/findPage\")\n ResultWrapper 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 ResultWrapper\n */\n @PostMapping(\"/insert\")\n ResultWrapper insert(@RequestBody #(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 修改\n * @param model 模型\n * @return ResultWrapper\n */\n @PostMapping(\"/update\")\n ResultWrapper update(@RequestBody #(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 删除\n * @param id ID\n * @return ResultWrapper\n */\n @PostMapping(\"/del\")\n ResultWrapper del(String id);\n\n /**\n * #(data.codeTitle) 批量删除\n * @param ids ID 数组\n * @return ResultWrapper\n */\n @PostMapping(\"/delAll\")\n ResultWrapper 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 ResultWrapper\n */\n @PostMapping(\"/importExcel\")\n ResultWrapper 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); +INSERT INTO `gen_template_detail` VALUES (1469919954038595585, 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.springframework.security.access.prepost.PreAuthorize;\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 ResultWrapper\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 ResultWrapper<#(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 ResultWrapper\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 ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {\n\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), 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 ResultWrapper\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 ResultWrapper 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 ResultWrapper\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 ResultWrapper 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 ResultWrapper\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 ResultWrapper 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 ResultWrapper\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 ResultWrapper 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<>(IService.getEntityClass(), 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 ResultWrapper\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 ResultWrapper 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, 1, '2021-12-12 14:40:01', 1, '2021-12-12 14:40:01'); INSERT INTO `gen_template_detail` VALUES (1469919954235727874, 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02'); INSERT INTO `gen_template_detail` VALUES (1469919954428665858, 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02'); INSERT INTO `gen_template_detail` VALUES (1469919954567077890, 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, 1, '2021-12-12 14:40:02', 1, '2021-12-12 14:40:02'); @@ -81,4 +81,4 @@ INSERT INTO `sys_role_menu_ref`(`id`, `menu_id`, `role_id`) VALUES (150573083683 INSERT INTO `sys_role_menu_ref`(`id`, `menu_id`, `role_id`) VALUES (1504780316210511896, 1504780214448308226, 1463431580473810945); -SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file +SET FOREIGN_KEY_CHECKS = 1; diff --git a/db-file/升级SQL/1.6.3 =》1.6.4.sql b/db-file/1.x版本/升级SQL/1.6.3 =》1.6.4.sql similarity index 100% rename from db-file/升级SQL/1.6.3 =》1.6.4.sql rename to db-file/1.x版本/升级SQL/1.6.3 =》1.6.4.sql diff --git a/db-file/2.0版本/Dockerfile b/db-file/2.0版本/Dockerfile new file mode 100644 index 0000000..c0714d8 --- /dev/null +++ b/db-file/2.0版本/Dockerfile @@ -0,0 +1,14 @@ +FROM mysql:8.0.19 + +MAINTAINER opsli.com +LABEL version=V1.3.3 +LABEL description=OPSLI-快速开发平台 +LABEL qqGroup=724850675 + +ENV TZ=Asia/Shanghai + +# 切换为上海时区 +RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \ + && echo $TZ > /etc/timezone + +COPY ./opsli-boot.sql /docker-entrypoint-initdb.d \ No newline at end of file diff --git a/db-file/2.0版本/opsli-boot.sql b/db-file/2.0版本/opsli-boot.sql new file mode 100644 index 0000000..2471ebd --- /dev/null +++ b/db-file/2.0版本/opsli-boot.sql @@ -0,0 +1,4768 @@ +/* + Navicat Premium Data Transfer + + Source Server : 本地数据库连接 + Source Server Type : MySQL + Source Server Version : 80018 + Source Host : localhost:3306 + Source Schema : opsli-boot + + Target Server Type : MySQL + Target Server Version : 80018 + File Encoding : 65001 + + Date: 03/08/2022 18:58:02 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for gen_logs +-- ---------------------------- +DROP TABLE IF EXISTS `gen_logs`; +CREATE TABLE `gen_logs` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `table_id` bigint(19) NOT NULL COMMENT '归属表ID', + `table_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表类型', + `package_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '生成包名', + `module_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '生成模块名', + `sub_module_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '生成子模块名', + `code_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '代码标题', + `code_title_brief` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '代码标题简介', + `author_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '作者名', + `template_id` bigint(19) NOT NULL COMMENT '模板ID', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `table` (`id`,`table_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成器 - 生成日志'; + +-- ---------------------------- +-- Table structure for gen_table +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table`; +CREATE TABLE `gen_table` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `table_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表名称', + `old_table_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表名称', + `table_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表类型', + `comments` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '描述', + `jdbc_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '数据库类型 { MySQL\\Oracle\\SQLServer ...}', + `iz_sync` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '同步', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注信息', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE, + KEY `creater_table_name` (`table_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成器 - 表信息'; + +-- ---------------------------- +-- Records of gen_table +-- ---------------------------- +BEGIN; +INSERT INTO `gen_table` VALUES (1340630022558056449, 'test_car', 'test_car', '0', '测试汽车', 'mysql', '1', NULL, 1, 1313694379541635074, '2020-12-20 20:08:00', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table` VALUES (1356152016136482817, 'test_car_copy1', 'test_car_copy1', '0', '测试', 'mysql', '1', NULL, 0, 1313694379541635074, '2021-02-01 16:06:51', 1313694379541635074, '2021-02-01 16:06:51'); +INSERT INTO `gen_table` VALUES (1359428685312028674, 'other_crypto_asymmetric', 'other_crypto_asymmetric', '0', '非对称加密表', 'mysql', '1', NULL, 12, 1313694379541635074, '2021-02-10 17:07:10', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table` VALUES (1397541427197468673, 'test_user', 'test_user', '0', '某系统用户', 'mysql', '0', NULL, 1, 1313694379541635074, '2021-05-26 21:13:36', 1313694379541635074, '2021-05-26 21:29:06'); +INSERT INTO `gen_table` VALUES (1504350321445097473, 'sys_login_log', 'sys_login_log', '0', '登录信息表', 'mysql', '0', NULL, 1, 1465171199435362305, '2022-03-17 14:54:01', 1465171199435362305, '2022-03-17 14:58:42'); +INSERT INTO `gen_table` VALUES (1520935845472522241, 'aaaa', 'aaaa', '0', 'aadsasd', 'mysql', '0', NULL, 0, 1465171199435362305, '2022-05-02 09:18:58', 1465171199435362305, '2022-05-02 09:18:58'); +INSERT INTO `gen_table` VALUES (1551878342172237826, 'operation_log', 'operation_log', '0', '业务操作日志', 'mysql', '0', NULL, 1, 1, '2022-07-26 18:33:24', 1, '2022-07-26 19:06:55'); +COMMIT; + +-- ---------------------------- +-- Table structure for gen_table_column +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table_column`; +CREATE TABLE `gen_table_column` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `table_id` bigint(19) NOT NULL COMMENT '归属表ID', + `field_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字段名称', + `field_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字段类型', + `field_length` int(11) DEFAULT NULL COMMENT '字段长度', + `field_precision` int(11) DEFAULT NULL COMMENT '字段精度', + `field_comments` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字段描述', + `iz_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否主键', + `iz_not_null` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否可为空', + `iz_show_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否列表字段', + `iz_show_form` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否表单显示', + `query_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '检索类别', + `java_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Java数据类型', + `show_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段生成方案(文本框、文本域、下拉框、复选框、单选框、字典选择、人员选择、部门选择、区域选择)', + `dict_type_code` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典类型', + `sort` smallint(6) NOT NULL COMMENT '排序(升序)', + `validate_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '验证类别', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE, + KEY `creater_table_column_sort` (`sort`) USING BTREE, + KEY `creater_table_column_table_id` (`table_id`,`field_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成器 - 表结构\r\n'; + +-- ---------------------------- +-- Records of gen_table_column +-- ---------------------------- +BEGIN; +INSERT INTO `gen_table_column` VALUES (1340630728203567106, 1340630022558056449, 'id', 'bigint', 19, 0, '主键', '1', '1', '0', '0', NULL, 'String', NULL, NULL, 0, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728220344321, 1340630022558056449, 'car_name', 'varchar', 20, 0, '汽车名称', '0', '1', '1', '1', 'EQ', 'String', '0', NULL, 1, 'IS_GENERAL_WITH_CHINESE', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728232927234, 1340630022558056449, 'car_type', 'varchar', 20, 0, '汽车类型', '0', '1', '1', '1', 'LIKE', 'String', '0', NULL, 2, 'IS_GENERAL_WITH_CHINESE', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728241315842, 1340630022558056449, 'car_brand', 'varchar', 50, 0, '汽车品牌', '0', '0', '1', '1', 'LIKE', 'String', '0', NULL, 3, 'IS_GENERAL_WITH_CHINESE', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728249704449, 1340630022558056449, 'produce_data', 'date', 0, 0, '生产日期', '0', '1', '1', '1', 'RANGE', 'Date', '4', NULL, 4, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728258093057, 1340630022558056449, 'iz_usable', 'char', 1, 0, '是否启用', '0', '1', '1', '1', 'EQ', 'String', '2', 'no_yes', 5, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728270675970, 1340630022558056449, 'tenant_id', 'bigint', 19, 0, '多租户ID', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 6, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728274870274, 1340630022558056449, 'deleted', 'char', 1, 0, '删除标记:0未删除,1删除', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 7, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728283258881, 1340630022558056449, 'version', 'int', 10, 0, '版本号(乐观锁)', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 8, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728291647489, 1340630022558056449, 'create_by', 'bigint', 19, 0, '创建用户', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 9, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728295841793, 1340630022558056449, 'create_time', 'datetime', 0, 0, '创建日期', '0', '1', '0', '0', NULL, 'Date', NULL, NULL, 10, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728304230401, 1340630022558056449, 'update_by', 'bigint', 19, 0, '修改用户', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 11, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1340630728308424706, 1340630022558056449, 'update_time', 'datetime', 0, 0, '修改日期', '0', '1', '0', '0', NULL, 'Date', NULL, NULL, 12, '', 0, 1313694379541635074, '2020-12-20 20:10:48', 1313694379541635074, '2020-12-20 20:10:48'); +INSERT INTO `gen_table_column` VALUES (1356152016623022081, 1356152016136482817, 'id', 'bigint', 19, 0, '主键', '1', '1', NULL, NULL, NULL, 'String', NULL, NULL, 0, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016715296769, 1356152016136482817, 'car_name', 'varchar', 20, NULL, '汽车名称', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 1, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016753045506, 1356152016136482817, 'car_type', 'varchar', 20, NULL, '汽车类型', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 2, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016794988546, 1356152016136482817, 'car_brand', 'varchar', 50, NULL, '汽车品牌', '0', '0', NULL, NULL, NULL, 'String', NULL, NULL, 3, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016824348673, 1356152016136482817, 'produce_data', 'date', NULL, NULL, '生产日期', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 4, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016874680321, 1356152016136482817, 'iz_usable', 'char', 1, NULL, '是否启用', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 5, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016916623361, 1356152016136482817, 'tenant_id', 'bigint', 19, 0, '多租户ID', '0', '0', NULL, NULL, NULL, 'String', NULL, NULL, 6, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016958566401, 1356152016136482817, 'deleted', 'char', 1, NULL, '删除标记:0未删除,1删除', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 7, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152016992120833, 1356152016136482817, 'version', 'int', 10, 0, '版本号(乐观锁)', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 8, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152017050841090, 1356152016136482817, 'create_by', 'bigint', 19, 0, '创建用户', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 9, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152017096978433, 1356152016136482817, 'create_time', 'datetime', NULL, NULL, '创建日期', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 10, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152017138921473, 1356152016136482817, 'update_by', 'bigint', 19, 0, '修改用户', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 11, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1356152017180864513, 1356152016136482817, 'update_time', 'datetime', NULL, NULL, '修改日期', '0', '1', NULL, NULL, NULL, 'String', NULL, NULL, 12, NULL, 0, 1313694379541635074, '2021-02-01 16:06:52', 1313694379541635074, '2021-02-01 16:06:52'); +INSERT INTO `gen_table_column` VALUES (1397532779008155650, 1359428685312028674, 'id', 'bigint', 19, 0, '唯一主键', '1', '1', '0', '0', NULL, 'String', NULL, NULL, 0, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779071070210, 1359428685312028674, 'public_key', 'blob', 2000, 0, '公钥', '0', '1', '1', '1', '', 'Byte[]', '1', NULL, 1, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779104624641, 1359428685312028674, 'private_key', 'varchar', 2000, 0, '私钥', '0', '1', '1', '1', '', 'String', '1', NULL, 2, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779121401857, 1359428685312028674, 'version', 'int', 10, 0, '版本(乐观锁)', '0', '1', '0', '0', NULL, 'Integer', NULL, NULL, 3, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779154956290, 1359428685312028674, 'crypto_type', 'varchar', 100, 0, '加解密类别', '0', '1', '1', '1', 'EQ', 'Integer', '0', NULL, 4, 'IS_INTEGER,IS_LETTER,IS_IP,IS_UPPER_CASE,IS_LOWER_CASE', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779171733506, 1359428685312028674, 'create_by', 'bigint', 19, 0, '创建用户', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 5, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779188510722, 1359428685312028674, 'create_time', 'datetime', 0, 0, '创建日期', '0', '1', '0', '0', NULL, 'Date', NULL, NULL, 6, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779205287937, 1359428685312028674, 'update_by', 'bigint', 19, 0, '修改用户', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 7, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397532779230453761, 1359428685312028674, 'update_time', 'datetime', 0, 0, '修改日期', '0', '1', '0', '0', NULL, 'Date', NULL, NULL, 8, '', 0, 1313694379541635074, '2021-05-26 20:39:14', 1313694379541635074, '2021-05-26 20:39:14'); +INSERT INTO `gen_table_column` VALUES (1397545330655850497, 1397541427197468673, 'id', 'bigint', 19, 0, '主键', '1', '1', '0', '0', NULL, 'String', NULL, NULL, 0, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330727153666, 1397541427197468673, 'name', 'varchar', 50, 0, '名称', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 1, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330752319489, 1397541427197468673, 'money', 'double', 6, 2, '金钱', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 2, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330769096706, 1397541427197468673, 'age', 'smallint', 5, 0, '年龄', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 3, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330785873921, 1397541427197468673, 'birth', 'date', 0, 0, '生日', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 4, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330811039746, 1397541427197468673, 'iz_usable', 'char', 1, 0, '是否启用', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 5, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330827816962, 1397541427197468673, 'tenant_id', 'bigint', 19, 0, '多租户ID', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 6, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330844594178, 1397541427197468673, 'deleted', 'char', 1, 0, '删除标记:0未删除,1删除', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 7, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330861371393, 1397541427197468673, 'version', 'int', 10, 0, '版本号(乐观锁)', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 8, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330869760002, 1397541427197468673, 'create_by', 'bigint', 19, 0, '创建用户', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 9, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330886537218, 1397541427197468673, 'create_time', 'datetime', 0, 0, '创建日期', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 10, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330903314433, 1397541427197468673, 'update_by', 'bigint', 19, 0, '修改用户', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 11, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330920091649, 1397541427197468673, 'update_time', 'datetime', 0, 0, '修改日期', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 12, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1397545330928480257, 1397541427197468673, 'ts', 'timestamp', 0, 0, '时间戳', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 13, '', 0, 1313694379541635074, '2021-05-26 21:29:07', 1313694379541635074, '2021-05-26 21:29:07'); +INSERT INTO `gen_table_column` VALUES (1504351504435957761, 1504350321445097473, 'id', 'bigint', 19, 0, '唯一主键', '1', '1', '0', '0', NULL, 'String', NULL, NULL, 0, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351504498872322, 1504350321445097473, 'org_ids', 'varchar', 500, 0, '父级主键集合', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 1, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351504565981185, 1504350321445097473, 'type', 'char', 1, 0, '日志类型', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 2, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351504633090050, 1504350321445097473, 'remote_addr', 'varchar', 255, 0, '操作IP地址', '0', '0', '1', '0', '', 'String', '0', NULL, 4, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351504691810306, 1504350321445097473, 'user_agent', 'varchar', 255, 0, '用户代理', '0', '0', '1', '0', '', 'String', '0', NULL, 5, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351504821833730, 1504350321445097473, 'username', 'varchar', 32, 0, '登录账户', '0', '1', '1', '0', 'LIKE', 'String', '0', NULL, 6, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351504884748290, 1504350321445097473, 'tenant_id', 'bigint', 19, 0, '多租户ID', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 7, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351505027354625, 1504350321445097473, 'version', 'int', 10, 0, '版本', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 8, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351505073491969, 1504350321445097473, 'create_by', 'bigint', 19, 0, '创建者', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 9, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351505203515394, 1504350321445097473, 'create_time', 'datetime', 0, 0, '创建时间', '0', '1', '1', '0', '', 'String', '0', NULL, 10, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351505270624257, 1504350321445097473, 'update_by', 'bigint', 19, 0, '修改人', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 11, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1504351505337733122, 1504350321445097473, 'update_time', 'datetime', 0, 0, '修改时间', '0', '1', '0', '0', NULL, 'String', NULL, NULL, 12, '', 0, 1465171199435362305, '2022-03-17 14:58:43', 1465171199435362305, '2022-03-17 14:58:43'); +INSERT INTO `gen_table_column` VALUES (1520935845673848833, 1520935845472522241, 'id', 'integer', 0, 0, 'qqqq', '0', '0', '1', '1', 'EQ', 'String', '0', '', 0, '', 0, 1465171199435362305, '2022-05-02 09:18:58', 1465171199435362305, '2022-05-02 09:18:58'); +INSERT INTO `gen_table_column` VALUES (1551886778654023681, 1551878342172237826, 'id', 'bigint', 19, 0, '日志ID', '1', '1', '0', '0', NULL, 'String', NULL, NULL, 0, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778691772417, 1551878342172237826, 'level', 'varchar', 8, 0, '日志等级', '0', '0', '1', '1', 'EQ', 'String', '2', 'level', 1, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778729521153, 1551878342172237826, 'module_id', 'varchar', 20, 0, '被操作的系统模块', '0', '0', '1', '1', 'EQ', 'String', '2', 'model_type', 2, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778763075585, 1551878342172237826, 'method', 'varchar', 100, 0, '方法名', '0', '0', '0', '1', '', 'String', '0', NULL, 3, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778805018625, 1551878342172237826, 'args', 'text', 20000, 0, '参数', '0', '0', '0', '1', '', 'String', '0', NULL, 4, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778842767362, 1551878342172237826, 'user_id', 'bigint', 19, 0, '操作人id', '0', '0', '0', '0', '', 'String', '', NULL, 5, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778884710401, 1551878342172237826, 'user_name', 'varchar', 32, 0, '操作账号', '0', '0', '1', '1', '', 'String', '0', NULL, 6, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778918264833, 1551878342172237826, 'real_name', 'varchar', 50, 0, '操作名称', '0', '0', '1', '1', '', 'String', '0', NULL, 7, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778947624961, 1551878342172237826, 'description', 'varchar', 255, 0, '日志描述', '0', '0', '1', '1', '', 'String', '0', NULL, 8, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886778976985089, 1551878342172237826, 'operation_type', 'varchar', 20, 0, '操作类型', '0', '0', '1', '1', 'EQ', 'String', '2', 'operation_type', 9, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779014733826, 1551878342172237826, 'run_time', 'bigint', 19, 0, '方法运行时间', '0', '0', '1', '0', '', 'String', '0', NULL, 10, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779052482562, 1551878342172237826, 'return_value', 'text', 20000, 0, '方法返回值', '0', '0', '0', '1', '', 'String', '0', NULL, 11, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779094425602, 1551878342172237826, 'log_type', 'varchar', 8, 0, '日志请求类型', '0', '0', '0', '1', '', 'String', '2', 'log_type', 12, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779132174337, 1551878342172237826, 'version', 'int', 10, 0, '版本(乐观锁)', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 13, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779157340161, 1551878342172237826, 'create_by', 'bigint', 19, 0, '创建者', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 14, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779182505985, 1551878342172237826, 'create_time', 'datetime', 0, 0, '创建时间', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 15, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779220254721, 1551878342172237826, 'update_by', 'bigint', 19, 0, '修改人', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 16, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +INSERT INTO `gen_table_column` VALUES (1551886779270586369, 1551878342172237826, 'update_time', 'datetime', 0, 0, '修改时间', '0', '0', '0', '0', NULL, 'String', NULL, NULL, 17, '', 0, 1, '2022-07-26 19:06:55', 1, '2022-07-26 19:06:55'); +COMMIT; + +-- ---------------------------- +-- Table structure for gen_template +-- ---------------------------- +DROP TABLE IF EXISTS `gen_template`; +CREATE TABLE `gen_template` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `temp_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板名称', + `table_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表类型', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注信息', + `version` int(10) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成器 - 模板'; + +-- ---------------------------- +-- Records of gen_template +-- ---------------------------- +BEGIN; +INSERT INTO `gen_template` VALUES (1398253704724828162, 'Form表单', '0', '默认Form表单', 40, 1313694379541635074, '2021-05-28 20:23:56', 1, '2022-07-27 13:11:12'); +COMMIT; + +-- ---------------------------- +-- Table structure for gen_template_detail +-- ---------------------------- +DROP TABLE IF EXISTS `gen_template_detail`; +CREATE TABLE `gen_template_detail` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `parent_id` bigint(19) NOT NULL COMMENT '父级ID', + `type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型 0 后端 / 1 前端', + `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '路径', + `file_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件名', + `file_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件内容', + `ignore_file_name` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '忽略文件名', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE, + KEY `creater_table_name` (`path`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代码生成器 - 表信息'; + +-- ---------------------------- +-- Records of gen_template_detail +-- ---------------------------- +BEGIN; +INSERT INTO `gen_template_detail` VALUES (1552159694968872961, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/entity', '${model.tableHumpName}Entity.java', '#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}', '1', 0, 1, '2022-07-27 13:11:24', 1, '2022-07-27 13:11:24'); +INSERT INTO `gen_template_detail` VALUES (1552159713998430210, 1398253704724828162, '0', '${packageName}/${moduleName}/${subModuleName}/mapper', '${model.tableHumpName}Mapper.java', '#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}', '0', 0, 1, '2022-07-27 13:11:28', 1, '2022-07-27 13:11:28'); +INSERT INTO `gen_template_detail` VALUES (1552159719581048833, 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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722206683138, 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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722336706561, 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 org.opsli.api.base.result.ResultWrapper;\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 ResultWrapper\n */\n @GetMapping(\"/get\")\n ResultWrapper<#(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 ResultWrapper\n */\n @GetMapping(\"/findPage\")\n ResultWrapper 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 ResultWrapper\n */\n @PostMapping(\"/insert\")\n ResultWrapper insert(@RequestBody #(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 修改\n * @param model 模型\n * @return ResultWrapper\n */\n @PostMapping(\"/update\")\n ResultWrapper update(@RequestBody #(data.model.tableHumpName)Model model);\n\n /**\n * #(data.codeTitle) 删除\n * @param id ID\n * @return ResultWrapper\n */\n @PostMapping(\"/del\")\n ResultWrapper del(String id);\n\n /**\n * #(data.codeTitle) 批量删除\n * @param ids ID 数组\n * @return ResultWrapper\n */\n @PostMapping(\"/delAll\")\n ResultWrapper 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 ResultWrapper\n */\n @PostMapping(\"/importExcel\")\n ResultWrapper 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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722433175553, 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 #(apiPath).base.result.ResultWrapper;\nimport org.opsli.common.annotation.ApiRestController;\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;\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.opsli.core.log.enums.*;\nimport org.opsli.core.log.annotation.OperateLogger;\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 ResultWrapper\n */\n @ApiOperation(value = \"获得单条#(data.codeTitleBrief)\", notes = \"获得单条#(data.codeTitleBrief) - ID\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_select\')\")\n #end\n @Override\n public ResultWrapper<#(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 ResultWrapper.getSuccessResultWrapper(model);\n }\n\n /**\n * #(data.codeTitleBrief) 查询分页\n * @param pageNo 当前页\n * @param pageSize 每页条数\n * @param request request\n * @return ResultWrapper\n */\n @ApiOperation(value = \"获得分页数据\", notes = \"获得分页数据 - 查询构造器\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_select\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_select\')\")\n #end\n @Override\n public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {\n\n QueryBuilder<#(data.model.tableHumpName)> queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), 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 ResultWrapper.getSuccessResultWrapper(page.getPageData());\n }\n\n /**\n * #(data.codeTitleBrief) 新增\n * @param model 模型\n * @return ResultWrapper\n */\n @ApiOperation(value = \"新增#(data.codeTitleBrief)数据\", notes = \"新增#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_insert\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_insert\')\")\n #end\n @OperateLogger(description = \"新增#(data.codeTitleBrief)数据\",\n module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.INSERT, db = true)\n @Override\n public ResultWrapper insert(#(data.model.tableHumpName)Model model) {\n // 调用新增方法\n IService.insert(model);\n return ResultWrapper.getSuccessResultWrapperByMsg(\"新增#(data.codeTitleBrief)成功\");\n }\n\n /**\n * #(data.codeTitleBrief) 修改\n * @param model 模型\n * @return ResultWrapper\n */\n @ApiOperation(value = \"修改#(data.codeTitleBrief)数据\", notes = \"修改#(data.codeTitleBrief)数据\")\n #if(data.subModuleName != null && data.subModuleName != \"\")\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_update\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_update\')\")\n #end \n @OperateLogger(description = \"修改#(data.codeTitleBrief)数据\",\n module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.UPDATE, db = true)\n @Override\n public ResultWrapper update(#(data.model.tableHumpName)Model model) {\n // 调用修改方法\n IService.update(model);\n return ResultWrapper.getSuccessResultWrapperByMsg(\"修改#(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 @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_delete\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_delete\')\")\n #end \n @OperateLogger(description = \"删除#(data.codeTitleBrief)数据\",\n module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.DELETE, db = true)\n @Override\n public ResultWrapper del(String id){\n IService.delete(id);\n return ResultWrapper.getSuccessResultWrapperByMsg(\"删除#(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 @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_delete\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_delete\')\")\n #end \n @OperateLogger(description = \"批量删除#(data.codeTitleBrief)数据\",\n module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.DELETE, db = true)\n @Override\n public ResultWrapper delAll(String ids){\n String[] idArray = Convert.toStrArray(ids);\n IService.deleteAll(idArray);\n return ResultWrapper.getSuccessResultWrapperByMsg(\"批量删除#(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 @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_export\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_export\')\")\n #end \n @OperateLogger(description = \"#(data.codeTitleBrief) Excel 导出\",\n module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.SELECT, db = true)\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<>(IService.getEntityClass(), 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 @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_import\')\")\n #end \n @OperateLogger(description = \"#(data.codeTitleBrief) Excel 导入\",\n module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.INSERT, db = true)\n @Override\n public ResultWrapper 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 @PreAuthorize(\"hasAuthority(\'#(data.moduleName.toLowerCase())_#(data.subModuleName.toLowerCase())_import\')\")\n #else\n @PreAuthorize(\"hasAuthority(\'#(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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722538033154, 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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722609336322, 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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722693222401, 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, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722772914178, 1398253704724828162, '1', 'src/views/modules/${moduleName}/${subModuleName}/components', '${model.tableHumpName}ManagementEdit.vue', '\n\n\n', '0', 0, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722856800258, 1398253704724828162, '1', 'src/views/modules/${moduleName}/${subModuleName}/components', '${model.tableHumpName}ManagementImport.vue', '\n\n\n', '0', 0, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +INSERT INTO `gen_template_detail` VALUES (1552159722944880641, 1398253704724828162, '1', 'src/views/modules/${moduleName}/${subModuleName}', 'index.vue', '\n\n\n', '0', 0, 1, '2022-07-27 13:11:30', 1, '2022-07-27 13:11:30'); +COMMIT; + +-- ---------------------------- +-- Table structure for operation_log +-- ---------------------------- +DROP TABLE IF EXISTS `operation_log`; +CREATE TABLE `operation_log` ( + `id` bigint(20) NOT NULL COMMENT '日志ID', + `level` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志等级', + `module_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '被操作的系统模块', + `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '方法名', + `args` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '参数', + `user_id` bigint(20) DEFAULT NULL COMMENT '操作人id', + `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作账号', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作名称', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志描述', + `operation_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作类型', + `run_time` bigint(20) DEFAULT NULL COMMENT '方法运行时间', + `return_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '方法返回值', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `log_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志请求类型', + `version` int(11) DEFAULT '0' COMMENT '版本(乐观锁)', + `create_by` bigint(19) DEFAULT NULL COMMENT '创建者', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', + `update_by` bigint(19) DEFAULT NULL COMMENT '修改人', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_module_id` (`module_id`) USING BTREE, + KEY `idx_method` (`method`) USING BTREE, + KEY `idx_operation_type` (`operation_type`) USING BTREE, + KEY `idx_log_type` (`log_type`) USING BTREE, + KEY `idx_user` (`user_id`) USING BTREE, + KEY `idx_tenant` (`tenant_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='业务操作日志'; + +-- ---------------------------- +-- Table structure for sys_area +-- ---------------------------- +DROP TABLE IF EXISTS `sys_area`; +CREATE TABLE `sys_area` ( + `id` bigint(19) NOT NULL COMMENT '唯一主键', + `parent_id` bigint(19) DEFAULT NULL COMMENT '上级ID', + `area_code` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '地域编号', + `area_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '地域名称', + `area_type` int(5) NOT NULL COMMENT '地域类型', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标记:0未删除,1删除', + `version` int(11) NOT NULL DEFAULT '0' COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `area` (`area_code`) USING BTREE, + KEY `parent_id` (`parent_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='地区表'; + +-- ---------------------------- +-- Records of sys_area +-- ---------------------------- +BEGIN; +INSERT INTO `sys_area` VALUES (86, 0, '86', '中国', 0, '0', 3, 1, '2020-12-28 17:43:30', 1, '2021-01-25 17:36:59', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110000, 86, '110000', '北京市', 1, '0', 1, 1, '2020-12-28 17:43:30', 1, '2022-07-25 19:57:19', '2022-07-25 19:57:19'); +INSERT INTO `sys_area` VALUES (110101, 110000, '110101', '东城区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110102, 110000, '110102', '西城区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110105, 110000, '110105', '朝阳区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110106, 110000, '110106', '丰台区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110107, 110000, '110107', '石景山区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110108, 110000, '110108', '海淀区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110109, 110000, '110109', '门头沟区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110111, 110000, '110111', '房山区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110112, 110000, '110112', '通州区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110113, 110000, '110113', '顺义区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110114, 110000, '110114', '昌平区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110115, 110000, '110115', '大兴区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110116, 110000, '110116', '怀柔区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110117, 110000, '110117', '平谷区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110118, 110000, '110118', '密云区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (110119, 110000, '110119', '延庆区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120000, 86, '120000', '天津市', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120101, 120000, '120101', '和平区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120102, 120000, '120102', '河东区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120103, 120000, '120103', '河西区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120104, 120000, '120104', '南开区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120105, 120000, '120105', '河北区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120106, 120000, '120106', '红桥区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120110, 120000, '120110', '东丽区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120111, 120000, '120111', '西青区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120112, 120000, '120112', '津南区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120113, 120000, '120113', '北辰区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120114, 120000, '120114', '武清区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120115, 120000, '120115', '宝坻区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120116, 120000, '120116', '滨海新区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120117, 120000, '120117', '宁河区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120118, 120000, '120118', '静海区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (120119, 120000, '120119', '蓟州区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130000, 86, '130000', '河北省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130100, 130000, '130100', '石家庄市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130102, 130100, '130102', '长安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130104, 130100, '130104', '桥西区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130105, 130100, '130105', '新华区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130107, 130100, '130107', '井陉矿区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130108, 130100, '130108', '裕华区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130109, 130100, '130109', '藁城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130110, 130100, '130110', '鹿泉区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130111, 130100, '130111', '栾城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130121, 130100, '130121', '井陉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130123, 130100, '130123', '正定县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130125, 130100, '130125', '行唐县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130126, 130100, '130126', '灵寿县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130127, 130100, '130127', '高邑县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130128, 130100, '130128', '深泽县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130129, 130100, '130129', '赞皇县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130130, 130100, '130130', '无极县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130131, 130100, '130131', '平山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130132, 130100, '130132', '元氏县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130133, 130100, '130133', '赵县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130181, 130100, '130181', '辛集市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130183, 130100, '130183', '晋州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130184, 130100, '130184', '新乐市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130200, 130000, '130200', '唐山市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130202, 130200, '130202', '路南区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130203, 130200, '130203', '路北区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130204, 130200, '130204', '古冶区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130205, 130200, '130205', '开平区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130207, 130200, '130207', '丰南区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130208, 130200, '130208', '丰润区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130209, 130200, '130209', '曹妃甸区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130224, 130200, '130224', '滦南县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130225, 130200, '130225', '乐亭县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130227, 130200, '130227', '迁西县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130229, 130200, '130229', '玉田县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130281, 130200, '130281', '遵化市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130283, 130200, '130283', '迁安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130284, 130200, '130284', '滦州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130300, 130000, '130300', '秦皇岛市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130302, 130300, '130302', '海港区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130303, 130300, '130303', '山海关区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130304, 130300, '130304', '北戴河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130306, 130300, '130306', '抚宁区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130321, 130300, '130321', '青龙满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130322, 130300, '130322', '昌黎县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130324, 130300, '130324', '卢龙县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130400, 130000, '130400', '邯郸市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130402, 130400, '130402', '邯山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130403, 130400, '130403', '丛台区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130404, 130400, '130404', '复兴区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130406, 130400, '130406', '峰峰矿区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130407, 130400, '130407', '肥乡区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130408, 130400, '130408', '永年区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130423, 130400, '130423', '临漳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130424, 130400, '130424', '成安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130425, 130400, '130425', '大名县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130426, 130400, '130426', '涉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130427, 130400, '130427', '磁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130430, 130400, '130430', '邱县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130431, 130400, '130431', '鸡泽县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130432, 130400, '130432', '广平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130433, 130400, '130433', '馆陶县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130434, 130400, '130434', '魏县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130435, 130400, '130435', '曲周县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130481, 130400, '130481', '武安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130500, 130000, '130500', '邢台市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130502, 130500, '130502', '襄都区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130503, 130500, '130503', '信都区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130505, 130500, '130505', '任泽区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130506, 130500, '130506', '南和区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130522, 130500, '130522', '临城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130523, 130500, '130523', '内丘县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130524, 130500, '130524', '柏乡县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130525, 130500, '130525', '隆尧县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130528, 130500, '130528', '宁晋县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130529, 130500, '130529', '巨鹿县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130530, 130500, '130530', '新河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130531, 130500, '130531', '广宗县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130532, 130500, '130532', '平乡县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130533, 130500, '130533', '威县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130534, 130500, '130534', '清河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130535, 130500, '130535', '临西县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130581, 130500, '130581', '南宫市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130582, 130500, '130582', '沙河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130600, 130000, '130600', '保定市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130602, 130600, '130602', '竞秀区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130606, 130600, '130606', '莲池区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130607, 130600, '130607', '满城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130608, 130600, '130608', '清苑区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130609, 130600, '130609', '徐水区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130623, 130600, '130623', '涞水县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130624, 130600, '130624', '阜平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130626, 130600, '130626', '定兴县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130627, 130600, '130627', '唐县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130628, 130600, '130628', '高阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130629, 130600, '130629', '容城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130630, 130600, '130630', '涞源县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130631, 130600, '130631', '望都县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130632, 130600, '130632', '安新县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130633, 130600, '130633', '易县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130634, 130600, '130634', '曲阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130635, 130600, '130635', '蠡县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130636, 130600, '130636', '顺平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130637, 130600, '130637', '博野县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130638, 130600, '130638', '雄县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130681, 130600, '130681', '涿州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130682, 130600, '130682', '定州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130683, 130600, '130683', '安国市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130684, 130600, '130684', '高碑店市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130700, 130000, '130700', '张家口市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130702, 130700, '130702', '桥东区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130703, 130700, '130703', '桥西区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130705, 130700, '130705', '宣化区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130706, 130700, '130706', '下花园区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130708, 130700, '130708', '万全区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130709, 130700, '130709', '崇礼区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130722, 130700, '130722', '张北县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130723, 130700, '130723', '康保县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130724, 130700, '130724', '沽源县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130725, 130700, '130725', '尚义县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130726, 130700, '130726', '蔚县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130727, 130700, '130727', '阳原县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130728, 130700, '130728', '怀安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130730, 130700, '130730', '怀来县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130731, 130700, '130731', '涿鹿县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130732, 130700, '130732', '赤城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130800, 130000, '130800', '承德市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130802, 130800, '130802', '双桥区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130803, 130800, '130803', '双滦区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130804, 130800, '130804', '鹰手营子矿区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130821, 130800, '130821', '承德县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130822, 130800, '130822', '兴隆县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130824, 130800, '130824', '滦平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130825, 130800, '130825', '隆化县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130826, 130800, '130826', '丰宁满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130827, 130800, '130827', '宽城满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130828, 130800, '130828', '围场满族蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130881, 130800, '130881', '平泉市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130900, 130000, '130900', '沧州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130902, 130900, '130902', '新华区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130903, 130900, '130903', '运河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130921, 130900, '130921', '沧县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130922, 130900, '130922', '青县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130923, 130900, '130923', '东光县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130924, 130900, '130924', '海兴县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130925, 130900, '130925', '盐山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130926, 130900, '130926', '肃宁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130927, 130900, '130927', '南皮县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130928, 130900, '130928', '吴桥县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130929, 130900, '130929', '献县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130930, 130900, '130930', '孟村回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130981, 130900, '130981', '泊头市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130982, 130900, '130982', '任丘市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130983, 130900, '130983', '黄骅市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (130984, 130900, '130984', '河间市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131000, 130000, '131000', '廊坊市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131002, 131000, '131002', '安次区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131003, 131000, '131003', '广阳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131022, 131000, '131022', '固安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131023, 131000, '131023', '永清县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131024, 131000, '131024', '香河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131025, 131000, '131025', '大城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131026, 131000, '131026', '文安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131028, 131000, '131028', '大厂回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131081, 131000, '131081', '霸州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131082, 131000, '131082', '三河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131100, 130000, '131100', '衡水市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131102, 131100, '131102', '桃城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131103, 131100, '131103', '冀州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131121, 131100, '131121', '枣强县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131122, 131100, '131122', '武邑县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131123, 131100, '131123', '武强县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131124, 131100, '131124', '饶阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131125, 131100, '131125', '安平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131126, 131100, '131126', '故城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131127, 131100, '131127', '景县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131128, 131100, '131128', '阜城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (131182, 131100, '131182', '深州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140000, 86, '140000', '山西省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140100, 140000, '140100', '太原市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140105, 140100, '140105', '小店区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140106, 140100, '140106', '迎泽区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140107, 140100, '140107', '杏花岭区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140108, 140100, '140108', '尖草坪区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140109, 140100, '140109', '万柏林区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140110, 140100, '140110', '晋源区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140121, 140100, '140121', '清徐县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140122, 140100, '140122', '阳曲县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140123, 140100, '140123', '娄烦县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140181, 140100, '140181', '古交市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140200, 140000, '140200', '大同市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140212, 140200, '140212', '新荣区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140213, 140200, '140213', '平城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140214, 140200, '140214', '云冈区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140215, 140200, '140215', '云州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140221, 140200, '140221', '阳高县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140222, 140200, '140222', '天镇县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140223, 140200, '140223', '广灵县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140224, 140200, '140224', '灵丘县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140225, 140200, '140225', '浑源县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140226, 140200, '140226', '左云县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140300, 140000, '140300', '阳泉市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140302, 140300, '140302', '城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140303, 140300, '140303', '矿区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140311, 140300, '140311', '郊区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140321, 140300, '140321', '平定县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140322, 140300, '140322', '盂县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140400, 140000, '140400', '长治市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140403, 140400, '140403', '潞州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140404, 140400, '140404', '上党区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140405, 140400, '140405', '屯留区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140406, 140400, '140406', '潞城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140423, 140400, '140423', '襄垣县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140425, 140400, '140425', '平顺县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140426, 140400, '140426', '黎城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140427, 140400, '140427', '壶关县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140428, 140400, '140428', '长子县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140429, 140400, '140429', '武乡县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140430, 140400, '140430', '沁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140431, 140400, '140431', '沁源县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140500, 140000, '140500', '晋城市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140502, 140500, '140502', '城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140521, 140500, '140521', '沁水县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140522, 140500, '140522', '阳城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140524, 140500, '140524', '陵川县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140525, 140500, '140525', '泽州县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140581, 140500, '140581', '高平市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140600, 140000, '140600', '朔州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140602, 140600, '140602', '朔城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140603, 140600, '140603', '平鲁区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140621, 140600, '140621', '山阴县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140622, 140600, '140622', '应县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140623, 140600, '140623', '右玉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140681, 140600, '140681', '怀仁市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140700, 140000, '140700', '晋中市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140702, 140700, '140702', '榆次区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140703, 140700, '140703', '太谷区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140721, 140700, '140721', '榆社县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140722, 140700, '140722', '左权县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140723, 140700, '140723', '和顺县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140724, 140700, '140724', '昔阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140725, 140700, '140725', '寿阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140727, 140700, '140727', '祁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140728, 140700, '140728', '平遥县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140729, 140700, '140729', '灵石县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140781, 140700, '140781', '介休市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140800, 140000, '140800', '运城市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140802, 140800, '140802', '盐湖区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140821, 140800, '140821', '临猗县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140822, 140800, '140822', '万荣县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140823, 140800, '140823', '闻喜县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140824, 140800, '140824', '稷山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140825, 140800, '140825', '新绛县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140826, 140800, '140826', '绛县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140827, 140800, '140827', '垣曲县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140828, 140800, '140828', '夏县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140829, 140800, '140829', '平陆县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140830, 140800, '140830', '芮城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140881, 140800, '140881', '永济市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140882, 140800, '140882', '河津市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140900, 140000, '140900', '忻州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140902, 140900, '140902', '忻府区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140921, 140900, '140921', '定襄县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140922, 140900, '140922', '五台县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140923, 140900, '140923', '代县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140924, 140900, '140924', '繁峙县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140925, 140900, '140925', '宁武县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140926, 140900, '140926', '静乐县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140927, 140900, '140927', '神池县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140928, 140900, '140928', '五寨县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140929, 140900, '140929', '岢岚县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140930, 140900, '140930', '河曲县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140931, 140900, '140931', '保德县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140932, 140900, '140932', '偏关县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (140981, 140900, '140981', '原平市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141000, 140000, '141000', '临汾市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141002, 141000, '141002', '尧都区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141021, 141000, '141021', '曲沃县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141022, 141000, '141022', '翼城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141023, 141000, '141023', '襄汾县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141024, 141000, '141024', '洪洞县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141025, 141000, '141025', '古县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141026, 141000, '141026', '安泽县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141027, 141000, '141027', '浮山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141028, 141000, '141028', '吉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141029, 141000, '141029', '乡宁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141030, 141000, '141030', '大宁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141031, 141000, '141031', '隰县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141032, 141000, '141032', '永和县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141033, 141000, '141033', '蒲县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141034, 141000, '141034', '汾西县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141081, 141000, '141081', '侯马市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141082, 141000, '141082', '霍州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141100, 140000, '141100', '吕梁市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141102, 141100, '141102', '离石区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141121, 141100, '141121', '文水县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141122, 141100, '141122', '交城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141123, 141100, '141123', '兴县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141124, 141100, '141124', '临县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141125, 141100, '141125', '柳林县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141126, 141100, '141126', '石楼县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141127, 141100, '141127', '岚县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141128, 141100, '141128', '方山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141129, 141100, '141129', '中阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141130, 141100, '141130', '交口县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141181, 141100, '141181', '孝义市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (141182, 141100, '141182', '汾阳市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150000, 86, '150000', '内蒙古自治区', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150100, 150000, '150100', '呼和浩特市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150102, 150100, '150102', '新城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150103, 150100, '150103', '回民区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150104, 150100, '150104', '玉泉区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150105, 150100, '150105', '赛罕区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150121, 150100, '150121', '土默特左旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150122, 150100, '150122', '托克托县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150123, 150100, '150123', '和林格尔县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150124, 150100, '150124', '清水河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150125, 150100, '150125', '武川县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150200, 150000, '150200', '包头市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150202, 150200, '150202', '东河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150203, 150200, '150203', '昆都仑区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150204, 150200, '150204', '青山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150205, 150200, '150205', '石拐区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150206, 150200, '150206', '白云鄂博矿区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150207, 150200, '150207', '九原区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150221, 150200, '150221', '土默特右旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150222, 150200, '150222', '固阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150223, 150200, '150223', '达尔罕茂明安联合旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150300, 150000, '150300', '乌海市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150302, 150300, '150302', '海勃湾区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150303, 150300, '150303', '海南区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150304, 150300, '150304', '乌达区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150400, 150000, '150400', '赤峰市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150402, 150400, '150402', '红山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150403, 150400, '150403', '元宝山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150404, 150400, '150404', '松山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150421, 150400, '150421', '阿鲁科尔沁旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150422, 150400, '150422', '巴林左旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150423, 150400, '150423', '巴林右旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150424, 150400, '150424', '林西县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150425, 150400, '150425', '克什克腾旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150426, 150400, '150426', '翁牛特旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150428, 150400, '150428', '喀喇沁旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150429, 150400, '150429', '宁城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150430, 150400, '150430', '敖汉旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150500, 150000, '150500', '通辽市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150502, 150500, '150502', '科尔沁区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150521, 150500, '150521', '科尔沁左翼中旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150522, 150500, '150522', '科尔沁左翼后旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150523, 150500, '150523', '开鲁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150524, 150500, '150524', '库伦旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150525, 150500, '150525', '奈曼旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150526, 150500, '150526', '扎鲁特旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150581, 150500, '150581', '霍林郭勒市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150600, 150000, '150600', '鄂尔多斯市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150602, 150600, '150602', '东胜区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150603, 150600, '150603', '康巴什区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150621, 150600, '150621', '达拉特旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150622, 150600, '150622', '准格尔旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150623, 150600, '150623', '鄂托克前旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150624, 150600, '150624', '鄂托克旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150625, 150600, '150625', '杭锦旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150626, 150600, '150626', '乌审旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150627, 150600, '150627', '伊金霍洛旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150700, 150000, '150700', '呼伦贝尔市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150702, 150700, '150702', '海拉尔区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150703, 150700, '150703', '扎赉诺尔区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150721, 150700, '150721', '阿荣旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150722, 150700, '150722', '莫力达瓦达斡尔族自治旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150723, 150700, '150723', '鄂伦春自治旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150724, 150700, '150724', '鄂温克族自治旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150725, 150700, '150725', '陈巴尔虎旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150726, 150700, '150726', '新巴尔虎左旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150727, 150700, '150727', '新巴尔虎右旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150781, 150700, '150781', '满洲里市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150782, 150700, '150782', '牙克石市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150783, 150700, '150783', '扎兰屯市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150784, 150700, '150784', '额尔古纳市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150785, 150700, '150785', '根河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150800, 150000, '150800', '巴彦淖尔市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150802, 150800, '150802', '临河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150821, 150800, '150821', '五原县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150822, 150800, '150822', '磴口县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150823, 150800, '150823', '乌拉特前旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150824, 150800, '150824', '乌拉特中旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150825, 150800, '150825', '乌拉特后旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150826, 150800, '150826', '杭锦后旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150900, 150000, '150900', '乌兰察布市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150902, 150900, '150902', '集宁区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150921, 150900, '150921', '卓资县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150922, 150900, '150922', '化德县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150923, 150900, '150923', '商都县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150924, 150900, '150924', '兴和县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150925, 150900, '150925', '凉城县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150926, 150900, '150926', '察哈尔右翼前旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150927, 150900, '150927', '察哈尔右翼中旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150928, 150900, '150928', '察哈尔右翼后旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150929, 150900, '150929', '四子王旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (150981, 150900, '150981', '丰镇市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152200, 150000, '152200', '兴安盟', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152201, 152200, '152201', '乌兰浩特市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152202, 152200, '152202', '阿尔山市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152221, 152200, '152221', '科尔沁右翼前旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152222, 152200, '152222', '科尔沁右翼中旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152223, 152200, '152223', '扎赉特旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152224, 152200, '152224', '突泉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152500, 150000, '152500', '锡林郭勒盟', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152501, 152500, '152501', '二连浩特市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152502, 152500, '152502', '锡林浩特市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152522, 152500, '152522', '阿巴嘎旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152523, 152500, '152523', '苏尼特左旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152524, 152500, '152524', '苏尼特右旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152525, 152500, '152525', '东乌珠穆沁旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152526, 152500, '152526', '西乌珠穆沁旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152527, 152500, '152527', '太仆寺旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152528, 152500, '152528', '镶黄旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152529, 152500, '152529', '正镶白旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152530, 152500, '152530', '正蓝旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152531, 152500, '152531', '多伦县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152900, 150000, '152900', '阿拉善盟', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152921, 152900, '152921', '阿拉善左旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152922, 152900, '152922', '阿拉善右旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (152923, 152900, '152923', '额济纳旗', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210000, 86, '210000', '辽宁省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210100, 210000, '210100', '沈阳市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210102, 210100, '210102', '和平区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210103, 210100, '210103', '沈河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210104, 210100, '210104', '大东区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210105, 210100, '210105', '皇姑区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210106, 210100, '210106', '铁西区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210111, 210100, '210111', '苏家屯区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210112, 210100, '210112', '浑南区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210113, 210100, '210113', '沈北新区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210114, 210100, '210114', '于洪区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210115, 210100, '210115', '辽中区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210123, 210100, '210123', '康平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210124, 210100, '210124', '法库县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210181, 210100, '210181', '新民市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210200, 210000, '210200', '大连市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210202, 210200, '210202', '中山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210203, 210200, '210203', '西岗区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210204, 210200, '210204', '沙河口区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210211, 210200, '210211', '甘井子区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210212, 210200, '210212', '旅顺口区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210213, 210200, '210213', '金州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210214, 210200, '210214', '普兰店区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210224, 210200, '210224', '长海县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210281, 210200, '210281', '瓦房店市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210283, 210200, '210283', '庄河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210300, 210000, '210300', '鞍山市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210302, 210300, '210302', '铁东区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210303, 210300, '210303', '铁西区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210304, 210300, '210304', '立山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210311, 210300, '210311', '千山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210321, 210300, '210321', '台安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210323, 210300, '210323', '岫岩满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210381, 210300, '210381', '海城市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210400, 210000, '210400', '抚顺市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210402, 210400, '210402', '新抚区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210403, 210400, '210403', '东洲区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210404, 210400, '210404', '望花区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210411, 210400, '210411', '顺城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210421, 210400, '210421', '抚顺县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210422, 210400, '210422', '新宾满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210423, 210400, '210423', '清原满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210500, 210000, '210500', '本溪市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210502, 210500, '210502', '平山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210503, 210500, '210503', '溪湖区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210504, 210500, '210504', '明山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210505, 210500, '210505', '南芬区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210521, 210500, '210521', '本溪满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210522, 210500, '210522', '桓仁满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210600, 210000, '210600', '丹东市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210602, 210600, '210602', '元宝区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210603, 210600, '210603', '振兴区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210604, 210600, '210604', '振安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210624, 210600, '210624', '宽甸满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210681, 210600, '210681', '东港市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210682, 210600, '210682', '凤城市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210700, 210000, '210700', '锦州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210702, 210700, '210702', '古塔区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210703, 210700, '210703', '凌河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210711, 210700, '210711', '太和区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210726, 210700, '210726', '黑山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210727, 210700, '210727', '义县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210781, 210700, '210781', '凌海市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210782, 210700, '210782', '北镇市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210800, 210000, '210800', '营口市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210802, 210800, '210802', '站前区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210803, 210800, '210803', '西市区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210804, 210800, '210804', '鲅鱼圈区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210811, 210800, '210811', '老边区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210881, 210800, '210881', '盖州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210882, 210800, '210882', '大石桥市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210900, 210000, '210900', '阜新市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210902, 210900, '210902', '海州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210903, 210900, '210903', '新邱区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210904, 210900, '210904', '太平区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210905, 210900, '210905', '清河门区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210911, 210900, '210911', '细河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210921, 210900, '210921', '阜新蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (210922, 210900, '210922', '彰武县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211000, 210000, '211000', '辽阳市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211002, 211000, '211002', '白塔区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211003, 211000, '211003', '文圣区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211004, 211000, '211004', '宏伟区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211005, 211000, '211005', '弓长岭区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211011, 211000, '211011', '太子河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211021, 211000, '211021', '辽阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211081, 211000, '211081', '灯塔市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211100, 210000, '211100', '盘锦市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211102, 211100, '211102', '双台子区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211103, 211100, '211103', '兴隆台区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211104, 211100, '211104', '大洼区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211122, 211100, '211122', '盘山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211200, 210000, '211200', '铁岭市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211202, 211200, '211202', '银州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211204, 211200, '211204', '清河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211221, 211200, '211221', '铁岭县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211223, 211200, '211223', '西丰县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211224, 211200, '211224', '昌图县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211281, 211200, '211281', '调兵山市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211282, 211200, '211282', '开原市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211300, 210000, '211300', '朝阳市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211302, 211300, '211302', '双塔区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211303, 211300, '211303', '龙城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211321, 211300, '211321', '朝阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211322, 211300, '211322', '建平县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211324, 211300, '211324', '喀喇沁左翼蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211381, 211300, '211381', '北票市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211382, 211300, '211382', '凌源市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211400, 210000, '211400', '葫芦岛市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211402, 211400, '211402', '连山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211403, 211400, '211403', '龙港区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211404, 211400, '211404', '南票区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211421, 211400, '211421', '绥中县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211422, 211400, '211422', '建昌县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (211481, 211400, '211481', '兴城市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220000, 86, '220000', '吉林省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220100, 220000, '220100', '长春市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220102, 220100, '220102', '南关区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220103, 220100, '220103', '宽城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220104, 220100, '220104', '朝阳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220105, 220100, '220105', '二道区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220106, 220100, '220106', '绿园区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220112, 220100, '220112', '双阳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220113, 220100, '220113', '九台区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220122, 220100, '220122', '农安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220182, 220100, '220182', '榆树市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220183, 220100, '220183', '德惠市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220184, 220100, '220184', '公主岭市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220200, 220000, '220200', '吉林市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220202, 220200, '220202', '昌邑区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220203, 220200, '220203', '龙潭区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220204, 220200, '220204', '船营区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220211, 220200, '220211', '丰满区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220221, 220200, '220221', '永吉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220281, 220200, '220281', '蛟河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220282, 220200, '220282', '桦甸市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220283, 220200, '220283', '舒兰市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220284, 220200, '220284', '磐石市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220300, 220000, '220300', '四平市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220302, 220300, '220302', '铁西区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220303, 220300, '220303', '铁东区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220322, 220300, '220322', '梨树县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220323, 220300, '220323', '伊通满族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220382, 220300, '220382', '双辽市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220400, 220000, '220400', '辽源市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220402, 220400, '220402', '龙山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220403, 220400, '220403', '西安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220421, 220400, '220421', '东丰县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220422, 220400, '220422', '东辽县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220500, 220000, '220500', '通化市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220502, 220500, '220502', '东昌区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220503, 220500, '220503', '二道江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220521, 220500, '220521', '通化县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220523, 220500, '220523', '辉南县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220524, 220500, '220524', '柳河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220581, 220500, '220581', '梅河口市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220582, 220500, '220582', '集安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220600, 220000, '220600', '白山市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220602, 220600, '220602', '浑江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220605, 220600, '220605', '江源区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220621, 220600, '220621', '抚松县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220622, 220600, '220622', '靖宇县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220623, 220600, '220623', '长白朝鲜族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220681, 220600, '220681', '临江市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220700, 220000, '220700', '松原市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220702, 220700, '220702', '宁江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220721, 220700, '220721', '前郭尔罗斯蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220722, 220700, '220722', '长岭县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220723, 220700, '220723', '乾安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220781, 220700, '220781', '扶余市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220800, 220000, '220800', '白城市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220802, 220800, '220802', '洮北区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220821, 220800, '220821', '镇赉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220822, 220800, '220822', '通榆县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220881, 220800, '220881', '洮南市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (220882, 220800, '220882', '大安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222400, 220000, '222400', '延边朝鲜族自治州', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222401, 222400, '222401', '延吉市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222402, 222400, '222402', '图们市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222403, 222400, '222403', '敦化市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222404, 222400, '222404', '珲春市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222405, 222400, '222405', '龙井市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222406, 222400, '222406', '和龙市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222424, 222400, '222424', '汪清县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (222426, 222400, '222426', '安图县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230000, 86, '230000', '黑龙江省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230100, 230000, '230100', '哈尔滨市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230102, 230100, '230102', '道里区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230103, 230100, '230103', '南岗区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230104, 230100, '230104', '道外区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230108, 230100, '230108', '平房区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230109, 230100, '230109', '松北区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230110, 230100, '230110', '香坊区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230111, 230100, '230111', '呼兰区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230112, 230100, '230112', '阿城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230113, 230100, '230113', '双城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230123, 230100, '230123', '依兰县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230124, 230100, '230124', '方正县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230125, 230100, '230125', '宾县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230126, 230100, '230126', '巴彦县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230127, 230100, '230127', '木兰县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230128, 230100, '230128', '通河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230129, 230100, '230129', '延寿县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230183, 230100, '230183', '尚志市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230184, 230100, '230184', '五常市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230200, 230000, '230200', '齐齐哈尔市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230202, 230200, '230202', '龙沙区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230203, 230200, '230203', '建华区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230204, 230200, '230204', '铁锋区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230205, 230200, '230205', '昂昂溪区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230206, 230200, '230206', '富拉尔基区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230207, 230200, '230207', '碾子山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230208, 230200, '230208', '梅里斯达斡尔族区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230221, 230200, '230221', '龙江县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230223, 230200, '230223', '依安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230224, 230200, '230224', '泰来县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230225, 230200, '230225', '甘南县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230227, 230200, '230227', '富裕县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230229, 230200, '230229', '克山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230230, 230200, '230230', '克东县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230231, 230200, '230231', '拜泉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230281, 230200, '230281', '讷河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230300, 230000, '230300', '鸡西市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230302, 230300, '230302', '鸡冠区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230303, 230300, '230303', '恒山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230304, 230300, '230304', '滴道区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230305, 230300, '230305', '梨树区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230306, 230300, '230306', '城子河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230307, 230300, '230307', '麻山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230321, 230300, '230321', '鸡东县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230381, 230300, '230381', '虎林市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230382, 230300, '230382', '密山市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230400, 230000, '230400', '鹤岗市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230402, 230400, '230402', '向阳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230403, 230400, '230403', '工农区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230404, 230400, '230404', '南山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230405, 230400, '230405', '兴安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230406, 230400, '230406', '东山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230407, 230400, '230407', '兴山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230421, 230400, '230421', '萝北县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230422, 230400, '230422', '绥滨县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230500, 230000, '230500', '双鸭山市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230502, 230500, '230502', '尖山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230503, 230500, '230503', '岭东区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230505, 230500, '230505', '四方台区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230506, 230500, '230506', '宝山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230521, 230500, '230521', '集贤县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230522, 230500, '230522', '友谊县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230523, 230500, '230523', '宝清县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230524, 230500, '230524', '饶河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230600, 230000, '230600', '大庆市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230602, 230600, '230602', '萨尔图区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230603, 230600, '230603', '龙凤区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230604, 230600, '230604', '让胡路区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230605, 230600, '230605', '红岗区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230606, 230600, '230606', '大同区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230621, 230600, '230621', '肇州县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230622, 230600, '230622', '肇源县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230623, 230600, '230623', '林甸县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230624, 230600, '230624', '杜尔伯特蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230700, 230000, '230700', '伊春市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230717, 230700, '230717', '伊美区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230718, 230700, '230718', '乌翠区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230719, 230700, '230719', '友好区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230722, 230700, '230722', '嘉荫县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230723, 230700, '230723', '汤旺县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230724, 230700, '230724', '丰林县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230725, 230700, '230725', '大箐山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230726, 230700, '230726', '南岔县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230751, 230700, '230751', '金林区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230781, 230700, '230781', '铁力市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230800, 230000, '230800', '佳木斯市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230803, 230800, '230803', '向阳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230804, 230800, '230804', '前进区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230805, 230800, '230805', '东风区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230811, 230800, '230811', '郊区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230822, 230800, '230822', '桦南县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230826, 230800, '230826', '桦川县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230828, 230800, '230828', '汤原县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230881, 230800, '230881', '同江市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230882, 230800, '230882', '富锦市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230883, 230800, '230883', '抚远市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230900, 230000, '230900', '七台河市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230902, 230900, '230902', '新兴区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230903, 230900, '230903', '桃山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230904, 230900, '230904', '茄子河区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (230921, 230900, '230921', '勃利县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231000, 230000, '231000', '牡丹江市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231002, 231000, '231002', '东安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231003, 231000, '231003', '阳明区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231004, 231000, '231004', '爱民区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231005, 231000, '231005', '西安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231025, 231000, '231025', '林口县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231081, 231000, '231081', '绥芬河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231083, 231000, '231083', '海林市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231084, 231000, '231084', '宁安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231085, 231000, '231085', '穆棱市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231086, 231000, '231086', '东宁市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231100, 230000, '231100', '黑河市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231102, 231100, '231102', '爱辉区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231123, 231100, '231123', '逊克县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231124, 231100, '231124', '孙吴县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231181, 231100, '231181', '北安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231182, 231100, '231182', '五大连池市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231183, 231100, '231183', '嫩江市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231200, 230000, '231200', '绥化市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231202, 231200, '231202', '北林区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231221, 231200, '231221', '望奎县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231222, 231200, '231222', '兰西县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231223, 231200, '231223', '青冈县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231224, 231200, '231224', '庆安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231225, 231200, '231225', '明水县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231226, 231200, '231226', '绥棱县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231281, 231200, '231281', '安达市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231282, 231200, '231282', '肇东市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (231283, 231200, '231283', '海伦市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (232700, 230000, '232700', '大兴安岭地区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (232701, 232700, '232701', '漠河市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (232721, 232700, '232721', '呼玛县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (232722, 232700, '232722', '塔河县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310000, 86, '310000', '上海市', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310101, 310000, '310101', '黄浦区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310104, 310000, '310104', '徐汇区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310105, 310000, '310105', '长宁区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310106, 310000, '310106', '静安区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310107, 310000, '310107', '普陀区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310109, 310000, '310109', '虹口区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310110, 310000, '310110', '杨浦区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310112, 310000, '310112', '闵行区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310113, 310000, '310113', '宝山区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310114, 310000, '310114', '嘉定区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310115, 310000, '310115', '浦东新区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310116, 310000, '310116', '金山区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310117, 310000, '310117', '松江区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310118, 310000, '310118', '青浦区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310120, 310000, '310120', '奉贤区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (310151, 310000, '310151', '崇明区', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320000, 86, '320000', '江苏省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320100, 320000, '320100', '南京市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320102, 320100, '320102', '玄武区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320104, 320100, '320104', '秦淮区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320105, 320100, '320105', '建邺区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320106, 320100, '320106', '鼓楼区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320111, 320100, '320111', '浦口区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320113, 320100, '320113', '栖霞区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320114, 320100, '320114', '雨花台区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320115, 320100, '320115', '江宁区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320116, 320100, '320116', '六合区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320117, 320100, '320117', '溧水区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320118, 320100, '320118', '高淳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320200, 320000, '320200', '无锡市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320205, 320200, '320205', '锡山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320206, 320200, '320206', '惠山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320211, 320200, '320211', '滨湖区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320213, 320200, '320213', '梁溪区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320214, 320200, '320214', '新吴区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320281, 320200, '320281', '江阴市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320282, 320200, '320282', '宜兴市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320300, 320000, '320300', '徐州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320302, 320300, '320302', '鼓楼区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320303, 320300, '320303', '云龙区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320305, 320300, '320305', '贾汪区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320311, 320300, '320311', '泉山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320312, 320300, '320312', '铜山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320321, 320300, '320321', '丰县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320322, 320300, '320322', '沛县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320324, 320300, '320324', '睢宁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320381, 320300, '320381', '新沂市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320382, 320300, '320382', '邳州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320400, 320000, '320400', '常州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320402, 320400, '320402', '天宁区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320404, 320400, '320404', '钟楼区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320411, 320400, '320411', '新北区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320412, 320400, '320412', '武进区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320413, 320400, '320413', '金坛区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320481, 320400, '320481', '溧阳市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320500, 320000, '320500', '苏州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320505, 320500, '320505', '虎丘区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320506, 320500, '320506', '吴中区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320507, 320500, '320507', '相城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320508, 320500, '320508', '姑苏区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320509, 320500, '320509', '吴江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320581, 320500, '320581', '常熟市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320582, 320500, '320582', '张家港市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320583, 320500, '320583', '昆山市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320585, 320500, '320585', '太仓市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320600, 320000, '320600', '南通市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320602, 320600, '320602', '崇川区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320611, 320600, '320611', '港闸区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320612, 320600, '320612', '通州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320623, 320600, '320623', '如东县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320681, 320600, '320681', '启东市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320682, 320600, '320682', '如皋市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320684, 320600, '320684', '海门市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320685, 320600, '320685', '海安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320700, 320000, '320700', '连云港市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320703, 320700, '320703', '连云区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320706, 320700, '320706', '海州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320707, 320700, '320707', '赣榆区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320722, 320700, '320722', '东海县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320723, 320700, '320723', '灌云县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320724, 320700, '320724', '灌南县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320800, 320000, '320800', '淮安市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320803, 320800, '320803', '淮安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320804, 320800, '320804', '淮阴区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320812, 320800, '320812', '清江浦区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320813, 320800, '320813', '洪泽区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320826, 320800, '320826', '涟水县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320830, 320800, '320830', '盱眙县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320831, 320800, '320831', '金湖县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320900, 320000, '320900', '盐城市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320902, 320900, '320902', '亭湖区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320903, 320900, '320903', '盐都区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320904, 320900, '320904', '大丰区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320921, 320900, '320921', '响水县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320922, 320900, '320922', '滨海县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320923, 320900, '320923', '阜宁县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320924, 320900, '320924', '射阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320925, 320900, '320925', '建湖县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (320981, 320900, '320981', '东台市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321000, 320000, '321000', '扬州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321002, 321000, '321002', '广陵区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321003, 321000, '321003', '邗江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321012, 321000, '321012', '江都区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321023, 321000, '321023', '宝应县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321081, 321000, '321081', '仪征市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321084, 321000, '321084', '高邮市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321100, 320000, '321100', '镇江市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321102, 321100, '321102', '京口区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321111, 321100, '321111', '润州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321112, 321100, '321112', '丹徒区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321181, 321100, '321181', '丹阳市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321182, 321100, '321182', '扬中市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321183, 321100, '321183', '句容市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321200, 320000, '321200', '泰州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321202, 321200, '321202', '海陵区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321203, 321200, '321203', '高港区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321204, 321200, '321204', '姜堰区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321281, 321200, '321281', '兴化市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321282, 321200, '321282', '靖江市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321283, 321200, '321283', '泰兴市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321300, 320000, '321300', '宿迁市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321302, 321300, '321302', '宿城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321311, 321300, '321311', '宿豫区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321322, 321300, '321322', '沭阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321323, 321300, '321323', '泗阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (321324, 321300, '321324', '泗洪县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330000, 86, '330000', '浙江省', 1, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330100, 330000, '330100', '杭州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330102, 330100, '330102', '上城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330103, 330100, '330103', '下城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330104, 330100, '330104', '江干区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330105, 330100, '330105', '拱墅区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330106, 330100, '330106', '西湖区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330108, 330100, '330108', '滨江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330109, 330100, '330109', '萧山区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330110, 330100, '330110', '余杭区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330111, 330100, '330111', '富阳区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330112, 330100, '330112', '临安区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330122, 330100, '330122', '桐庐县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330127, 330100, '330127', '淳安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330182, 330100, '330182', '建德市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330200, 330000, '330200', '宁波市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330203, 330200, '330203', '海曙区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330205, 330200, '330205', '江北区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330206, 330200, '330206', '北仑区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330211, 330200, '330211', '镇海区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330212, 330200, '330212', '鄞州区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330213, 330200, '330213', '奉化区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330225, 330200, '330225', '象山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330226, 330200, '330226', '宁海县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330281, 330200, '330281', '余姚市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330282, 330200, '330282', '慈溪市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330300, 330000, '330300', '温州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330302, 330300, '330302', '鹿城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330303, 330300, '330303', '龙湾区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330304, 330300, '330304', '瓯海区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330305, 330300, '330305', '洞头区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330324, 330300, '330324', '永嘉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330326, 330300, '330326', '平阳县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330327, 330300, '330327', '苍南县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330328, 330300, '330328', '文成县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330329, 330300, '330329', '泰顺县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330381, 330300, '330381', '瑞安市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330382, 330300, '330382', '乐清市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330383, 330300, '330383', '龙港市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330400, 330000, '330400', '嘉兴市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330402, 330400, '330402', '南湖区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330411, 330400, '330411', '秀洲区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330421, 330400, '330421', '嘉善县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330424, 330400, '330424', '海盐县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330481, 330400, '330481', '海宁市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330482, 330400, '330482', '平湖市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330483, 330400, '330483', '桐乡市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330500, 330000, '330500', '湖州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330502, 330500, '330502', '吴兴区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330503, 330500, '330503', '南浔区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330521, 330500, '330521', '德清县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330522, 330500, '330522', '长兴县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330523, 330500, '330523', '安吉县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330600, 330000, '330600', '绍兴市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330602, 330600, '330602', '越城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330603, 330600, '330603', '柯桥区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330604, 330600, '330604', '上虞区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330624, 330600, '330624', '新昌县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330681, 330600, '330681', '诸暨市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330683, 330600, '330683', '嵊州市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330700, 330000, '330700', '金华市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330702, 330700, '330702', '婺城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330703, 330700, '330703', '金东区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330723, 330700, '330723', '武义县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330726, 330700, '330726', '浦江县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330727, 330700, '330727', '磐安县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330781, 330700, '330781', '兰溪市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330782, 330700, '330782', '义乌市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330783, 330700, '330783', '东阳市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330784, 330700, '330784', '永康市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330800, 330000, '330800', '衢州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330802, 330800, '330802', '柯城区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330803, 330800, '330803', '衢江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330822, 330800, '330822', '常山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330824, 330800, '330824', '开化县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330825, 330800, '330825', '龙游县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330881, 330800, '330881', '江山市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330900, 330000, '330900', '舟山市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330902, 330900, '330902', '定海区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330903, 330900, '330903', '普陀区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330921, 330900, '330921', '岱山县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (330922, 330900, '330922', '嵊泗县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331000, 330000, '331000', '台州市', 2, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331002, 331000, '331002', '椒江区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331003, 331000, '331003', '黄岩区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331004, 331000, '331004', '路桥区', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331022, 331000, '331022', '三门县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331023, 331000, '331023', '天台县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331024, 331000, '331024', '仙居县', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331081, 331000, '331081', '温岭市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331082, 331000, '331082', '临海市', 3, '0', 0, 1, '2020-12-28 17:43:30', 1, '2020-12-28 17:43:30', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331083, 331000, '331083', '玉环市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331100, 330000, '331100', '丽水市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331102, 331100, '331102', '莲都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331121, 331100, '331121', '青田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331122, 331100, '331122', '缙云县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331123, 331100, '331123', '遂昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331124, 331100, '331124', '松阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331125, 331100, '331125', '云和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331126, 331100, '331126', '庆元县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331127, 331100, '331127', '景宁畲族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (331181, 331100, '331181', '龙泉市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340000, 86, '340000', '安徽省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340100, 340000, '340100', '合肥市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340102, 340100, '340102', '瑶海区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340103, 340100, '340103', '庐阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340104, 340100, '340104', '蜀山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340111, 340100, '340111', '包河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340121, 340100, '340121', '长丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340122, 340100, '340122', '肥东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340123, 340100, '340123', '肥西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340124, 340100, '340124', '庐江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340181, 340100, '340181', '巢湖市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340200, 340000, '340200', '芜湖市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340202, 340200, '340202', '镜湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340203, 340200, '340203', '弋江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340207, 340200, '340207', '鸠江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340208, 340200, '340208', '三山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340221, 340200, '340221', '芜湖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340222, 340200, '340222', '繁昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340223, 340200, '340223', '南陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340281, 340200, '340281', '无为市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340300, 340000, '340300', '蚌埠市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340302, 340300, '340302', '龙子湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340303, 340300, '340303', '蚌山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340304, 340300, '340304', '禹会区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340311, 340300, '340311', '淮上区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340321, 340300, '340321', '怀远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340322, 340300, '340322', '五河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340323, 340300, '340323', '固镇县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340400, 340000, '340400', '淮南市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340402, 340400, '340402', '大通区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340403, 340400, '340403', '田家庵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340404, 340400, '340404', '谢家集区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340405, 340400, '340405', '八公山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340406, 340400, '340406', '潘集区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340421, 340400, '340421', '凤台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340422, 340400, '340422', '寿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340500, 340000, '340500', '马鞍山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340503, 340500, '340503', '花山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340504, 340500, '340504', '雨山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340506, 340500, '340506', '博望区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340521, 340500, '340521', '当涂县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340522, 340500, '340522', '含山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340523, 340500, '340523', '和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340600, 340000, '340600', '淮北市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340602, 340600, '340602', '杜集区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340603, 340600, '340603', '相山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340604, 340600, '340604', '烈山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340621, 340600, '340621', '濉溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340700, 340000, '340700', '铜陵市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340705, 340700, '340705', '铜官区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340706, 340700, '340706', '义安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340711, 340700, '340711', '郊区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340722, 340700, '340722', '枞阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340800, 340000, '340800', '安庆市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340802, 340800, '340802', '迎江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340803, 340800, '340803', '大观区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340811, 340800, '340811', '宜秀区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340822, 340800, '340822', '怀宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340825, 340800, '340825', '太湖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340826, 340800, '340826', '宿松县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340827, 340800, '340827', '望江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340828, 340800, '340828', '岳西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340881, 340800, '340881', '桐城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (340882, 340800, '340882', '潜山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341000, 340000, '341000', '黄山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341002, 341000, '341002', '屯溪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341003, 341000, '341003', '黄山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341004, 341000, '341004', '徽州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341021, 341000, '341021', '歙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341022, 341000, '341022', '休宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341023, 341000, '341023', '黟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341024, 341000, '341024', '祁门县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341100, 340000, '341100', '滁州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341102, 341100, '341102', '琅琊区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341103, 341100, '341103', '南谯区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341122, 341100, '341122', '来安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341124, 341100, '341124', '全椒县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341125, 341100, '341125', '定远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341126, 341100, '341126', '凤阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341181, 341100, '341181', '天长市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341182, 341100, '341182', '明光市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341200, 340000, '341200', '阜阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341202, 341200, '341202', '颍州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341203, 341200, '341203', '颍东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341204, 341200, '341204', '颍泉区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341221, 341200, '341221', '临泉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341222, 341200, '341222', '太和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341225, 341200, '341225', '阜南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341226, 341200, '341226', '颍上县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341282, 341200, '341282', '界首市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341300, 340000, '341300', '宿州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341302, 341300, '341302', '埇桥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341321, 341300, '341321', '砀山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341322, 341300, '341322', '萧县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341323, 341300, '341323', '灵璧县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341324, 341300, '341324', '泗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341500, 340000, '341500', '六安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341502, 341500, '341502', '金安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341503, 341500, '341503', '裕安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341504, 341500, '341504', '叶集区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341522, 341500, '341522', '霍邱县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341523, 341500, '341523', '舒城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341524, 341500, '341524', '金寨县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341525, 341500, '341525', '霍山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341600, 340000, '341600', '亳州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341602, 341600, '341602', '谯城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341621, 341600, '341621', '涡阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341622, 341600, '341622', '蒙城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341623, 341600, '341623', '利辛县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341700, 340000, '341700', '池州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341702, 341700, '341702', '贵池区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341721, 341700, '341721', '东至县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341722, 341700, '341722', '石台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341723, 341700, '341723', '青阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341800, 340000, '341800', '宣城市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341802, 341800, '341802', '宣州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341821, 341800, '341821', '郎溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341823, 341800, '341823', '泾县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341824, 341800, '341824', '绩溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341825, 341800, '341825', '旌德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341881, 341800, '341881', '宁国市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (341882, 341800, '341882', '广德市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350000, 86, '350000', '福建省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350100, 350000, '350100', '福州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350102, 350100, '350102', '鼓楼区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350103, 350100, '350103', '台江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350104, 350100, '350104', '仓山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350105, 350100, '350105', '马尾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350111, 350100, '350111', '晋安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350112, 350100, '350112', '长乐区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350121, 350100, '350121', '闽侯县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350122, 350100, '350122', '连江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350123, 350100, '350123', '罗源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350124, 350100, '350124', '闽清县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350125, 350100, '350125', '永泰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350128, 350100, '350128', '平潭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350181, 350100, '350181', '福清市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350200, 350000, '350200', '厦门市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350203, 350200, '350203', '思明区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350205, 350200, '350205', '海沧区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350206, 350200, '350206', '湖里区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350211, 350200, '350211', '集美区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350212, 350200, '350212', '同安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350213, 350200, '350213', '翔安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350300, 350000, '350300', '莆田市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350302, 350300, '350302', '城厢区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350303, 350300, '350303', '涵江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350304, 350300, '350304', '荔城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350305, 350300, '350305', '秀屿区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350322, 350300, '350322', '仙游县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350400, 350000, '350400', '三明市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350402, 350400, '350402', '梅列区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350403, 350400, '350403', '三元区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350421, 350400, '350421', '明溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350423, 350400, '350423', '清流县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350424, 350400, '350424', '宁化县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350425, 350400, '350425', '大田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350426, 350400, '350426', '尤溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350427, 350400, '350427', '沙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350428, 350400, '350428', '将乐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350429, 350400, '350429', '泰宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350430, 350400, '350430', '建宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350481, 350400, '350481', '永安市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350500, 350000, '350500', '泉州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350502, 350500, '350502', '鲤城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350503, 350500, '350503', '丰泽区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350504, 350500, '350504', '洛江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350505, 350500, '350505', '泉港区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350521, 350500, '350521', '惠安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350524, 350500, '350524', '安溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350525, 350500, '350525', '永春县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350526, 350500, '350526', '德化县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350527, 350500, '350527', '金门县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350581, 350500, '350581', '石狮市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350582, 350500, '350582', '晋江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350583, 350500, '350583', '南安市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350600, 350000, '350600', '漳州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350602, 350600, '350602', '芗城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350603, 350600, '350603', '龙文区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350622, 350600, '350622', '云霄县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350623, 350600, '350623', '漳浦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350624, 350600, '350624', '诏安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350625, 350600, '350625', '长泰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350626, 350600, '350626', '东山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350627, 350600, '350627', '南靖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350628, 350600, '350628', '平和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350629, 350600, '350629', '华安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350681, 350600, '350681', '龙海市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350700, 350000, '350700', '南平市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350702, 350700, '350702', '延平区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350703, 350700, '350703', '建阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350721, 350700, '350721', '顺昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350722, 350700, '350722', '浦城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350723, 350700, '350723', '光泽县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350724, 350700, '350724', '松溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350725, 350700, '350725', '政和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350781, 350700, '350781', '邵武市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350782, 350700, '350782', '武夷山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350783, 350700, '350783', '建瓯市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350800, 350000, '350800', '龙岩市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350802, 350800, '350802', '新罗区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350803, 350800, '350803', '永定区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350821, 350800, '350821', '长汀县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350823, 350800, '350823', '上杭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350824, 350800, '350824', '武平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350825, 350800, '350825', '连城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350881, 350800, '350881', '漳平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350900, 350000, '350900', '宁德市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350902, 350900, '350902', '蕉城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350921, 350900, '350921', '霞浦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350922, 350900, '350922', '古田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350923, 350900, '350923', '屏南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350924, 350900, '350924', '寿宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350925, 350900, '350925', '周宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350926, 350900, '350926', '柘荣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350981, 350900, '350981', '福安市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (350982, 350900, '350982', '福鼎市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360000, 86, '360000', '江西省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360100, 360000, '360100', '南昌市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360102, 360100, '360102', '东湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360103, 360100, '360103', '西湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360104, 360100, '360104', '青云谱区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360111, 360100, '360111', '青山湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360112, 360100, '360112', '新建区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360113, 360100, '360113', '红谷滩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360121, 360100, '360121', '南昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360123, 360100, '360123', '安义县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360124, 360100, '360124', '进贤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360200, 360000, '360200', '景德镇市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360202, 360200, '360202', '昌江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360203, 360200, '360203', '珠山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360222, 360200, '360222', '浮梁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360281, 360200, '360281', '乐平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360300, 360000, '360300', '萍乡市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360302, 360300, '360302', '安源区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360313, 360300, '360313', '湘东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360321, 360300, '360321', '莲花县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360322, 360300, '360322', '上栗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360323, 360300, '360323', '芦溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360400, 360000, '360400', '九江市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360402, 360400, '360402', '濂溪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360403, 360400, '360403', '浔阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360404, 360400, '360404', '柴桑区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360423, 360400, '360423', '武宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360424, 360400, '360424', '修水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360425, 360400, '360425', '永修县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360426, 360400, '360426', '德安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360428, 360400, '360428', '都昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360429, 360400, '360429', '湖口县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360430, 360400, '360430', '彭泽县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360481, 360400, '360481', '瑞昌市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360482, 360400, '360482', '共青城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360483, 360400, '360483', '庐山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360500, 360000, '360500', '新余市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360502, 360500, '360502', '渝水区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360521, 360500, '360521', '分宜县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360600, 360000, '360600', '鹰潭市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360602, 360600, '360602', '月湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360603, 360600, '360603', '余江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360681, 360600, '360681', '贵溪市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360700, 360000, '360700', '赣州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360702, 360700, '360702', '章贡区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360703, 360700, '360703', '南康区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360704, 360700, '360704', '赣县区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360722, 360700, '360722', '信丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360723, 360700, '360723', '大余县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360724, 360700, '360724', '上犹县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360725, 360700, '360725', '崇义县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360726, 360700, '360726', '安远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360728, 360700, '360728', '定南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360729, 360700, '360729', '全南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360730, 360700, '360730', '宁都县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360731, 360700, '360731', '于都县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360732, 360700, '360732', '兴国县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360733, 360700, '360733', '会昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360734, 360700, '360734', '寻乌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360735, 360700, '360735', '石城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360781, 360700, '360781', '瑞金市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360783, 360700, '360783', '龙南市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360800, 360000, '360800', '吉安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360802, 360800, '360802', '吉州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360803, 360800, '360803', '青原区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360821, 360800, '360821', '吉安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360822, 360800, '360822', '吉水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360823, 360800, '360823', '峡江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360824, 360800, '360824', '新干县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360825, 360800, '360825', '永丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360826, 360800, '360826', '泰和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360827, 360800, '360827', '遂川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360828, 360800, '360828', '万安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360829, 360800, '360829', '安福县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360830, 360800, '360830', '永新县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360881, 360800, '360881', '井冈山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360900, 360000, '360900', '宜春市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360902, 360900, '360902', '袁州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360921, 360900, '360921', '奉新县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360922, 360900, '360922', '万载县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360923, 360900, '360923', '上高县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360924, 360900, '360924', '宜丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360925, 360900, '360925', '靖安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360926, 360900, '360926', '铜鼓县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360981, 360900, '360981', '丰城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360982, 360900, '360982', '樟树市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (360983, 360900, '360983', '高安市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361000, 360000, '361000', '抚州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361002, 361000, '361002', '临川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361003, 361000, '361003', '东乡区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361021, 361000, '361021', '南城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361022, 361000, '361022', '黎川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361023, 361000, '361023', '南丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361024, 361000, '361024', '崇仁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361025, 361000, '361025', '乐安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361026, 361000, '361026', '宜黄县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361027, 361000, '361027', '金溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361028, 361000, '361028', '资溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361030, 361000, '361030', '广昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361100, 360000, '361100', '上饶市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361102, 361100, '361102', '信州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361103, 361100, '361103', '广丰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361104, 361100, '361104', '广信区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361123, 361100, '361123', '玉山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361124, 361100, '361124', '铅山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361125, 361100, '361125', '横峰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361126, 361100, '361126', '弋阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361127, 361100, '361127', '余干县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361128, 361100, '361128', '鄱阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361129, 361100, '361129', '万年县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361130, 361100, '361130', '婺源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (361181, 361100, '361181', '德兴市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370000, 86, '370000', '山东省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370100, 370000, '370100', '济南市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370102, 370100, '370102', '历下区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370103, 370100, '370103', '市中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370104, 370100, '370104', '槐荫区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370105, 370100, '370105', '天桥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370112, 370100, '370112', '历城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370113, 370100, '370113', '长清区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370114, 370100, '370114', '章丘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370115, 370100, '370115', '济阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370116, 370100, '370116', '莱芜区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370117, 370100, '370117', '钢城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370124, 370100, '370124', '平阴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370126, 370100, '370126', '商河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370200, 370000, '370200', '青岛市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370202, 370200, '370202', '市南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370203, 370200, '370203', '市北区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370211, 370200, '370211', '黄岛区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370212, 370200, '370212', '崂山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370213, 370200, '370213', '李沧区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370214, 370200, '370214', '城阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370215, 370200, '370215', '即墨区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370281, 370200, '370281', '胶州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370283, 370200, '370283', '平度市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370285, 370200, '370285', '莱西市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370300, 370000, '370300', '淄博市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370302, 370300, '370302', '淄川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370303, 370300, '370303', '张店区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370304, 370300, '370304', '博山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370305, 370300, '370305', '临淄区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370306, 370300, '370306', '周村区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370321, 370300, '370321', '桓台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370322, 370300, '370322', '高青县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370323, 370300, '370323', '沂源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370400, 370000, '370400', '枣庄市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370402, 370400, '370402', '市中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370403, 370400, '370403', '薛城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370404, 370400, '370404', '峄城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370405, 370400, '370405', '台儿庄区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370406, 370400, '370406', '山亭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370481, 370400, '370481', '滕州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370500, 370000, '370500', '东营市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370502, 370500, '370502', '东营区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370503, 370500, '370503', '河口区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370505, 370500, '370505', '垦利区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370522, 370500, '370522', '利津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370523, 370500, '370523', '广饶县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370600, 370000, '370600', '烟台市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370602, 370600, '370602', '芝罘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370611, 370600, '370611', '福山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370612, 370600, '370612', '牟平区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370613, 370600, '370613', '莱山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370634, 370600, '370634', '长岛县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370681, 370600, '370681', '龙口市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370682, 370600, '370682', '莱阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370683, 370600, '370683', '莱州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370684, 370600, '370684', '蓬莱市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370685, 370600, '370685', '招远市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370686, 370600, '370686', '栖霞市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370687, 370600, '370687', '海阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370700, 370000, '370700', '潍坊市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370702, 370700, '370702', '潍城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370703, 370700, '370703', '寒亭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370704, 370700, '370704', '坊子区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370705, 370700, '370705', '奎文区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370724, 370700, '370724', '临朐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370725, 370700, '370725', '昌乐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370781, 370700, '370781', '青州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370782, 370700, '370782', '诸城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370783, 370700, '370783', '寿光市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370784, 370700, '370784', '安丘市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370785, 370700, '370785', '高密市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370786, 370700, '370786', '昌邑市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370800, 370000, '370800', '济宁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370811, 370800, '370811', '任城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370812, 370800, '370812', '兖州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370826, 370800, '370826', '微山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370827, 370800, '370827', '鱼台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370828, 370800, '370828', '金乡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370829, 370800, '370829', '嘉祥县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370830, 370800, '370830', '汶上县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370831, 370800, '370831', '泗水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370832, 370800, '370832', '梁山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370881, 370800, '370881', '曲阜市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370883, 370800, '370883', '邹城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370900, 370000, '370900', '泰安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370902, 370900, '370902', '泰山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370911, 370900, '370911', '岱岳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370921, 370900, '370921', '宁阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370923, 370900, '370923', '东平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370982, 370900, '370982', '新泰市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (370983, 370900, '370983', '肥城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371000, 370000, '371000', '威海市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371002, 371000, '371002', '环翠区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371003, 371000, '371003', '文登区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371082, 371000, '371082', '荣成市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371083, 371000, '371083', '乳山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371100, 370000, '371100', '日照市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371102, 371100, '371102', '东港区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371103, 371100, '371103', '岚山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371121, 371100, '371121', '五莲县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371122, 371100, '371122', '莒县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371300, 370000, '371300', '临沂市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371302, 371300, '371302', '兰山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371311, 371300, '371311', '罗庄区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371312, 371300, '371312', '河东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371321, 371300, '371321', '沂南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371322, 371300, '371322', '郯城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371323, 371300, '371323', '沂水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371324, 371300, '371324', '兰陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371325, 371300, '371325', '费县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371326, 371300, '371326', '平邑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371327, 371300, '371327', '莒南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371328, 371300, '371328', '蒙阴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371329, 371300, '371329', '临沭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371400, 370000, '371400', '德州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371402, 371400, '371402', '德城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371403, 371400, '371403', '陵城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371422, 371400, '371422', '宁津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371423, 371400, '371423', '庆云县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371424, 371400, '371424', '临邑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371425, 371400, '371425', '齐河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371426, 371400, '371426', '平原县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371427, 371400, '371427', '夏津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371428, 371400, '371428', '武城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371481, 371400, '371481', '乐陵市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371482, 371400, '371482', '禹城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371500, 370000, '371500', '聊城市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371502, 371500, '371502', '东昌府区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371503, 371500, '371503', '茌平区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371521, 371500, '371521', '阳谷县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371522, 371500, '371522', '莘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371524, 371500, '371524', '东阿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371525, 371500, '371525', '冠县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371526, 371500, '371526', '高唐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371581, 371500, '371581', '临清市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371600, 370000, '371600', '滨州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371602, 371600, '371602', '滨城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371603, 371600, '371603', '沾化区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371621, 371600, '371621', '惠民县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371622, 371600, '371622', '阳信县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371623, 371600, '371623', '无棣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371625, 371600, '371625', '博兴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371681, 371600, '371681', '邹平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371700, 370000, '371700', '菏泽市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371702, 371700, '371702', '牡丹区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371703, 371700, '371703', '定陶区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371721, 371700, '371721', '曹县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371722, 371700, '371722', '单县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371723, 371700, '371723', '成武县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371724, 371700, '371724', '巨野县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371725, 371700, '371725', '郓城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371726, 371700, '371726', '鄄城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (371728, 371700, '371728', '东明县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410000, 86, '410000', '河南省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410100, 410000, '410100', '郑州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410102, 410100, '410102', '中原区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410103, 410100, '410103', '二七区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410104, 410100, '410104', '管城回族区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410105, 410100, '410105', '金水区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410106, 410100, '410106', '上街区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410108, 410100, '410108', '惠济区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410122, 410100, '410122', '中牟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410181, 410100, '410181', '巩义市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410182, 410100, '410182', '荥阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410183, 410100, '410183', '新密市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410184, 410100, '410184', '新郑市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410185, 410100, '410185', '登封市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410200, 410000, '410200', '开封市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410202, 410200, '410202', '龙亭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410203, 410200, '410203', '顺河回族区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410204, 410200, '410204', '鼓楼区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410205, 410200, '410205', '禹王台区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410212, 410200, '410212', '祥符区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410221, 410200, '410221', '杞县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410222, 410200, '410222', '通许县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410223, 410200, '410223', '尉氏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410225, 410200, '410225', '兰考县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410300, 410000, '410300', '洛阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410302, 410300, '410302', '老城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410303, 410300, '410303', '西工区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410304, 410300, '410304', '瀍河回族区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410305, 410300, '410305', '涧西区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410306, 410300, '410306', '吉利区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410311, 410300, '410311', '洛龙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410322, 410300, '410322', '孟津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410323, 410300, '410323', '新安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410324, 410300, '410324', '栾川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410325, 410300, '410325', '嵩县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410326, 410300, '410326', '汝阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410327, 410300, '410327', '宜阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410328, 410300, '410328', '洛宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410329, 410300, '410329', '伊川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410381, 410300, '410381', '偃师市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410400, 410000, '410400', '平顶山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410402, 410400, '410402', '新华区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410403, 410400, '410403', '卫东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410404, 410400, '410404', '石龙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410411, 410400, '410411', '湛河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410421, 410400, '410421', '宝丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410422, 410400, '410422', '叶县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410423, 410400, '410423', '鲁山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410425, 410400, '410425', '郏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410481, 410400, '410481', '舞钢市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410482, 410400, '410482', '汝州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410500, 410000, '410500', '安阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410502, 410500, '410502', '文峰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410503, 410500, '410503', '北关区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410505, 410500, '410505', '殷都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410506, 410500, '410506', '龙安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410522, 410500, '410522', '安阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410523, 410500, '410523', '汤阴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410526, 410500, '410526', '滑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410527, 410500, '410527', '内黄县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410581, 410500, '410581', '林州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410600, 410000, '410600', '鹤壁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410602, 410600, '410602', '鹤山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410603, 410600, '410603', '山城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410611, 410600, '410611', '淇滨区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410621, 410600, '410621', '浚县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410622, 410600, '410622', '淇县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410700, 410000, '410700', '新乡市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410702, 410700, '410702', '红旗区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410703, 410700, '410703', '卫滨区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410704, 410700, '410704', '凤泉区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410711, 410700, '410711', '牧野区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410721, 410700, '410721', '新乡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410724, 410700, '410724', '获嘉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410725, 410700, '410725', '原阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410726, 410700, '410726', '延津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410727, 410700, '410727', '封丘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410781, 410700, '410781', '卫辉市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410782, 410700, '410782', '辉县市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410783, 410700, '410783', '长垣市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410800, 410000, '410800', '焦作市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410802, 410800, '410802', '解放区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410803, 410800, '410803', '中站区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410804, 410800, '410804', '马村区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410811, 410800, '410811', '山阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410821, 410800, '410821', '修武县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410822, 410800, '410822', '博爱县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410823, 410800, '410823', '武陟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410825, 410800, '410825', '温县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410882, 410800, '410882', '沁阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410883, 410800, '410883', '孟州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410900, 410000, '410900', '濮阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410902, 410900, '410902', '华龙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410922, 410900, '410922', '清丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410923, 410900, '410923', '南乐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410926, 410900, '410926', '范县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410927, 410900, '410927', '台前县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (410928, 410900, '410928', '濮阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411000, 410000, '411000', '许昌市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411002, 411000, '411002', '魏都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411003, 411000, '411003', '建安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411024, 411000, '411024', '鄢陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411025, 411000, '411025', '襄城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411081, 411000, '411081', '禹州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411082, 411000, '411082', '长葛市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411100, 410000, '411100', '漯河市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411102, 411100, '411102', '源汇区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411103, 411100, '411103', '郾城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411104, 411100, '411104', '召陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411121, 411100, '411121', '舞阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411122, 411100, '411122', '临颍县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411200, 410000, '411200', '三门峡市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411202, 411200, '411202', '湖滨区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411203, 411200, '411203', '陕州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411221, 411200, '411221', '渑池县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411224, 411200, '411224', '卢氏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411281, 411200, '411281', '义马市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411282, 411200, '411282', '灵宝市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411300, 410000, '411300', '南阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411302, 411300, '411302', '宛城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411303, 411300, '411303', '卧龙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411321, 411300, '411321', '南召县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411322, 411300, '411322', '方城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411323, 411300, '411323', '西峡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411324, 411300, '411324', '镇平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411325, 411300, '411325', '内乡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411326, 411300, '411326', '淅川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411327, 411300, '411327', '社旗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411328, 411300, '411328', '唐河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411329, 411300, '411329', '新野县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411330, 411300, '411330', '桐柏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411381, 411300, '411381', '邓州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411400, 410000, '411400', '商丘市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411402, 411400, '411402', '梁园区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411403, 411400, '411403', '睢阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411421, 411400, '411421', '民权县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411422, 411400, '411422', '睢县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411423, 411400, '411423', '宁陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411424, 411400, '411424', '柘城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411425, 411400, '411425', '虞城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411426, 411400, '411426', '夏邑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411481, 411400, '411481', '永城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411500, 410000, '411500', '信阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411502, 411500, '411502', '浉河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411503, 411500, '411503', '平桥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411521, 411500, '411521', '罗山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411522, 411500, '411522', '光山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411523, 411500, '411523', '新县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411524, 411500, '411524', '商城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411525, 411500, '411525', '固始县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411526, 411500, '411526', '潢川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411527, 411500, '411527', '淮滨县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411528, 411500, '411528', '息县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411600, 410000, '411600', '周口市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411602, 411600, '411602', '川汇区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411603, 411600, '411603', '淮阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411621, 411600, '411621', '扶沟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411622, 411600, '411622', '西华县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411623, 411600, '411623', '商水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411624, 411600, '411624', '沈丘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411625, 411600, '411625', '郸城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411627, 411600, '411627', '太康县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411628, 411600, '411628', '鹿邑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411681, 411600, '411681', '项城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411700, 410000, '411700', '驻马店市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411702, 411700, '411702', '驿城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411721, 411700, '411721', '西平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411722, 411700, '411722', '上蔡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411723, 411700, '411723', '平舆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411724, 411700, '411724', '正阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411725, 411700, '411725', '确山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411726, 411700, '411726', '泌阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411727, 411700, '411727', '汝南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411728, 411700, '411728', '遂平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (411729, 411700, '411729', '新蔡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (419001, 410000, '419001', '济源市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420000, 86, '420000', '湖北省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420100, 420000, '420100', '武汉市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420102, 420100, '420102', '江岸区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420103, 420100, '420103', '江汉区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420104, 420100, '420104', '硚口区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420105, 420100, '420105', '汉阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420106, 420100, '420106', '武昌区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420107, 420100, '420107', '青山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420111, 420100, '420111', '洪山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420112, 420100, '420112', '东西湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420113, 420100, '420113', '汉南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420114, 420100, '420114', '蔡甸区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420115, 420100, '420115', '江夏区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420116, 420100, '420116', '黄陂区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420117, 420100, '420117', '新洲区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420200, 420000, '420200', '黄石市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420202, 420200, '420202', '黄石港区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420203, 420200, '420203', '西塞山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420204, 420200, '420204', '下陆区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420205, 420200, '420205', '铁山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420222, 420200, '420222', '阳新县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420281, 420200, '420281', '大冶市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420300, 420000, '420300', '十堰市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420302, 420300, '420302', '茅箭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420303, 420300, '420303', '张湾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420304, 420300, '420304', '郧阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420322, 420300, '420322', '郧西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420323, 420300, '420323', '竹山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420324, 420300, '420324', '竹溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420325, 420300, '420325', '房县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420381, 420300, '420381', '丹江口市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420500, 420000, '420500', '宜昌市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420502, 420500, '420502', '西陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420503, 420500, '420503', '伍家岗区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420504, 420500, '420504', '点军区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420505, 420500, '420505', '猇亭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420506, 420500, '420506', '夷陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420525, 420500, '420525', '远安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420526, 420500, '420526', '兴山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420527, 420500, '420527', '秭归县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420528, 420500, '420528', '长阳土家族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420529, 420500, '420529', '五峰土家族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420581, 420500, '420581', '宜都市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420582, 420500, '420582', '当阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420583, 420500, '420583', '枝江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420600, 420000, '420600', '襄阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420602, 420600, '420602', '襄城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420606, 420600, '420606', '樊城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420607, 420600, '420607', '襄州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420624, 420600, '420624', '南漳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420625, 420600, '420625', '谷城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420626, 420600, '420626', '保康县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420682, 420600, '420682', '老河口市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420683, 420600, '420683', '枣阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420684, 420600, '420684', '宜城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420700, 420000, '420700', '鄂州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420702, 420700, '420702', '梁子湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420703, 420700, '420703', '华容区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420704, 420700, '420704', '鄂城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420800, 420000, '420800', '荆门市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420802, 420800, '420802', '东宝区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420804, 420800, '420804', '掇刀区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420822, 420800, '420822', '沙洋县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420881, 420800, '420881', '钟祥市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420882, 420800, '420882', '京山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420900, 420000, '420900', '孝感市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420902, 420900, '420902', '孝南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420921, 420900, '420921', '孝昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420922, 420900, '420922', '大悟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420923, 420900, '420923', '云梦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420981, 420900, '420981', '应城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420982, 420900, '420982', '安陆市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (420984, 420900, '420984', '汉川市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421000, 420000, '421000', '荆州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421002, 421000, '421002', '沙市区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421003, 421000, '421003', '荆州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421022, 421000, '421022', '公安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421023, 421000, '421023', '监利县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421024, 421000, '421024', '江陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421081, 421000, '421081', '石首市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421083, 421000, '421083', '洪湖市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421087, 421000, '421087', '松滋市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421100, 420000, '421100', '黄冈市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421102, 421100, '421102', '黄州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421121, 421100, '421121', '团风县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421122, 421100, '421122', '红安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421123, 421100, '421123', '罗田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421124, 421100, '421124', '英山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421125, 421100, '421125', '浠水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421126, 421100, '421126', '蕲春县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421127, 421100, '421127', '黄梅县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421181, 421100, '421181', '麻城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421182, 421100, '421182', '武穴市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421200, 420000, '421200', '咸宁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421202, 421200, '421202', '咸安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421221, 421200, '421221', '嘉鱼县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421222, 421200, '421222', '通城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421223, 421200, '421223', '崇阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421224, 421200, '421224', '通山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421281, 421200, '421281', '赤壁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421300, 420000, '421300', '随州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421303, 421300, '421303', '曾都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421321, 421300, '421321', '随县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (421381, 421300, '421381', '广水市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422800, 420000, '422800', '恩施土家族苗族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422801, 422800, '422801', '恩施市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422802, 422800, '422802', '利川市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422822, 422800, '422822', '建始县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422823, 422800, '422823', '巴东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422825, 422800, '422825', '宣恩县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422826, 422800, '422826', '咸丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422827, 422800, '422827', '来凤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (422828, 422800, '422828', '鹤峰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (429004, 420000, '429004', '仙桃市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (429005, 420000, '429005', '潜江市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (429006, 420000, '429006', '天门市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (429021, 420000, '429021', '神农架林区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430000, 86, '430000', '湖南省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430100, 430000, '430100', '长沙市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430102, 430100, '430102', '芙蓉区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430103, 430100, '430103', '天心区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430104, 430100, '430104', '岳麓区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430105, 430100, '430105', '开福区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430111, 430100, '430111', '雨花区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430112, 430100, '430112', '望城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430121, 430100, '430121', '长沙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430181, 430100, '430181', '浏阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430182, 430100, '430182', '宁乡市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430200, 430000, '430200', '株洲市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430202, 430200, '430202', '荷塘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430203, 430200, '430203', '芦淞区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430204, 430200, '430204', '石峰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430211, 430200, '430211', '天元区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430212, 430200, '430212', '渌口区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430223, 430200, '430223', '攸县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430224, 430200, '430224', '茶陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430225, 430200, '430225', '炎陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430281, 430200, '430281', '醴陵市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430300, 430000, '430300', '湘潭市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430302, 430300, '430302', '雨湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430304, 430300, '430304', '岳塘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430321, 430300, '430321', '湘潭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430381, 430300, '430381', '湘乡市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430382, 430300, '430382', '韶山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430400, 430000, '430400', '衡阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430405, 430400, '430405', '珠晖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430406, 430400, '430406', '雁峰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430407, 430400, '430407', '石鼓区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430408, 430400, '430408', '蒸湘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430412, 430400, '430412', '南岳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430421, 430400, '430421', '衡阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430422, 430400, '430422', '衡南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430423, 430400, '430423', '衡山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430424, 430400, '430424', '衡东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430426, 430400, '430426', '祁东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430481, 430400, '430481', '耒阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430482, 430400, '430482', '常宁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430500, 430000, '430500', '邵阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430502, 430500, '430502', '双清区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430503, 430500, '430503', '大祥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430511, 430500, '430511', '北塔区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430522, 430500, '430522', '新邵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430523, 430500, '430523', '邵阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430524, 430500, '430524', '隆回县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430525, 430500, '430525', '洞口县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430527, 430500, '430527', '绥宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430528, 430500, '430528', '新宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430529, 430500, '430529', '城步苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430581, 430500, '430581', '武冈市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430582, 430500, '430582', '邵东市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430600, 430000, '430600', '岳阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430602, 430600, '430602', '岳阳楼区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430603, 430600, '430603', '云溪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430611, 430600, '430611', '君山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430621, 430600, '430621', '岳阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430623, 430600, '430623', '华容县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430624, 430600, '430624', '湘阴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430626, 430600, '430626', '平江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430681, 430600, '430681', '汨罗市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430682, 430600, '430682', '临湘市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430700, 430000, '430700', '常德市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430702, 430700, '430702', '武陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430703, 430700, '430703', '鼎城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430721, 430700, '430721', '安乡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430722, 430700, '430722', '汉寿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430723, 430700, '430723', '澧县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430724, 430700, '430724', '临澧县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430725, 430700, '430725', '桃源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430726, 430700, '430726', '石门县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430781, 430700, '430781', '津市市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430800, 430000, '430800', '张家界市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430802, 430800, '430802', '永定区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430811, 430800, '430811', '武陵源区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430821, 430800, '430821', '慈利县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430822, 430800, '430822', '桑植县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430900, 430000, '430900', '益阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430902, 430900, '430902', '资阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430903, 430900, '430903', '赫山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430921, 430900, '430921', '南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430922, 430900, '430922', '桃江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430923, 430900, '430923', '安化县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (430981, 430900, '430981', '沅江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431000, 430000, '431000', '郴州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431002, 431000, '431002', '北湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431003, 431000, '431003', '苏仙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431021, 431000, '431021', '桂阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431022, 431000, '431022', '宜章县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431023, 431000, '431023', '永兴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431024, 431000, '431024', '嘉禾县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431025, 431000, '431025', '临武县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431026, 431000, '431026', '汝城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431027, 431000, '431027', '桂东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431028, 431000, '431028', '安仁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431081, 431000, '431081', '资兴市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431100, 430000, '431100', '永州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431102, 431100, '431102', '零陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431103, 431100, '431103', '冷水滩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431121, 431100, '431121', '祁阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431122, 431100, '431122', '东安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431123, 431100, '431123', '双牌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431124, 431100, '431124', '道县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431125, 431100, '431125', '江永县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431126, 431100, '431126', '宁远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431127, 431100, '431127', '蓝山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431128, 431100, '431128', '新田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431129, 431100, '431129', '江华瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431200, 430000, '431200', '怀化市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431202, 431200, '431202', '鹤城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431221, 431200, '431221', '中方县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431222, 431200, '431222', '沅陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431223, 431200, '431223', '辰溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431224, 431200, '431224', '溆浦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431225, 431200, '431225', '会同县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431226, 431200, '431226', '麻阳苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431227, 431200, '431227', '新晃侗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431228, 431200, '431228', '芷江侗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431229, 431200, '431229', '靖州苗族侗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431230, 431200, '431230', '通道侗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431281, 431200, '431281', '洪江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431300, 430000, '431300', '娄底市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431302, 431300, '431302', '娄星区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431321, 431300, '431321', '双峰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431322, 431300, '431322', '新化县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431381, 431300, '431381', '冷水江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (431382, 431300, '431382', '涟源市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433100, 430000, '433100', '湘西土家族苗族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433101, 433100, '433101', '吉首市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433122, 433100, '433122', '泸溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433123, 433100, '433123', '凤凰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433124, 433100, '433124', '花垣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433125, 433100, '433125', '保靖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433126, 433100, '433126', '古丈县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433127, 433100, '433127', '永顺县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (433130, 433100, '433130', '龙山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440000, 86, '440000', '广东省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440100, 440000, '440100', '广州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440103, 440100, '440103', '荔湾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440104, 440100, '440104', '越秀区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440105, 440100, '440105', '海珠区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440106, 440100, '440106', '天河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440111, 440100, '440111', '白云区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440112, 440100, '440112', '黄埔区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440113, 440100, '440113', '番禺区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440114, 440100, '440114', '花都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440115, 440100, '440115', '南沙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440117, 440100, '440117', '从化区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440118, 440100, '440118', '增城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440200, 440000, '440200', '韶关市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440203, 440200, '440203', '武江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440204, 440200, '440204', '浈江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440205, 440200, '440205', '曲江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440222, 440200, '440222', '始兴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440224, 440200, '440224', '仁化县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440229, 440200, '440229', '翁源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440232, 440200, '440232', '乳源瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440233, 440200, '440233', '新丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440281, 440200, '440281', '乐昌市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440282, 440200, '440282', '南雄市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440300, 440000, '440300', '深圳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440303, 440300, '440303', '罗湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440304, 440300, '440304', '福田区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440305, 440300, '440305', '南山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440306, 440300, '440306', '宝安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440307, 440300, '440307', '龙岗区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440308, 440300, '440308', '盐田区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440309, 440300, '440309', '龙华区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440310, 440300, '440310', '坪山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440311, 440300, '440311', '光明区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440400, 440000, '440400', '珠海市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440402, 440400, '440402', '香洲区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440403, 440400, '440403', '斗门区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440404, 440400, '440404', '金湾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440500, 440000, '440500', '汕头市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440507, 440500, '440507', '龙湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440511, 440500, '440511', '金平区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440512, 440500, '440512', '濠江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440513, 440500, '440513', '潮阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440514, 440500, '440514', '潮南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440515, 440500, '440515', '澄海区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440523, 440500, '440523', '南澳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440600, 440000, '440600', '佛山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440604, 440600, '440604', '禅城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440605, 440600, '440605', '南海区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440606, 440600, '440606', '顺德区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440607, 440600, '440607', '三水区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440608, 440600, '440608', '高明区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440700, 440000, '440700', '江门市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440703, 440700, '440703', '蓬江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440704, 440700, '440704', '江海区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440705, 440700, '440705', '新会区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440781, 440700, '440781', '台山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440783, 440700, '440783', '开平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440784, 440700, '440784', '鹤山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440785, 440700, '440785', '恩平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440800, 440000, '440800', '湛江市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440802, 440800, '440802', '赤坎区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440803, 440800, '440803', '霞山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440804, 440800, '440804', '坡头区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440811, 440800, '440811', '麻章区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440823, 440800, '440823', '遂溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440825, 440800, '440825', '徐闻县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440881, 440800, '440881', '廉江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440882, 440800, '440882', '雷州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440883, 440800, '440883', '吴川市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440900, 440000, '440900', '茂名市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440902, 440900, '440902', '茂南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440904, 440900, '440904', '电白区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440981, 440900, '440981', '高州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440982, 440900, '440982', '化州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (440983, 440900, '440983', '信宜市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441200, 440000, '441200', '肇庆市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441202, 441200, '441202', '端州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441203, 441200, '441203', '鼎湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441204, 441200, '441204', '高要区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441223, 441200, '441223', '广宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441224, 441200, '441224', '怀集县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441225, 441200, '441225', '封开县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441226, 441200, '441226', '德庆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441284, 441200, '441284', '四会市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441300, 440000, '441300', '惠州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441302, 441300, '441302', '惠城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441303, 441300, '441303', '惠阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441322, 441300, '441322', '博罗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441323, 441300, '441323', '惠东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441324, 441300, '441324', '龙门县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441400, 440000, '441400', '梅州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441402, 441400, '441402', '梅江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441403, 441400, '441403', '梅县区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441422, 441400, '441422', '大埔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441423, 441400, '441423', '丰顺县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441424, 441400, '441424', '五华县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441426, 441400, '441426', '平远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441427, 441400, '441427', '蕉岭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441481, 441400, '441481', '兴宁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441500, 440000, '441500', '汕尾市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441502, 441500, '441502', '城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441521, 441500, '441521', '海丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441523, 441500, '441523', '陆河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441581, 441500, '441581', '陆丰市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441600, 440000, '441600', '河源市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441602, 441600, '441602', '源城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441621, 441600, '441621', '紫金县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441622, 441600, '441622', '龙川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441623, 441600, '441623', '连平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441624, 441600, '441624', '和平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441625, 441600, '441625', '东源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441700, 440000, '441700', '阳江市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441702, 441700, '441702', '江城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441704, 441700, '441704', '阳东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441721, 441700, '441721', '阳西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441781, 441700, '441781', '阳春市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441800, 440000, '441800', '清远市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441802, 441800, '441802', '清城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441803, 441800, '441803', '清新区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441821, 441800, '441821', '佛冈县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441823, 441800, '441823', '阳山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441825, 441800, '441825', '连山壮族瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441826, 441800, '441826', '连南瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441881, 441800, '441881', '英德市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441882, 441800, '441882', '连州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (441900, 440000, '441900', '东莞市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (442000, 440000, '442000', '中山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445100, 440000, '445100', '潮州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445102, 445100, '445102', '湘桥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445103, 445100, '445103', '潮安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445122, 445100, '445122', '饶平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445200, 440000, '445200', '揭阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445202, 445200, '445202', '榕城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445203, 445200, '445203', '揭东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445222, 445200, '445222', '揭西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445224, 445200, '445224', '惠来县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445281, 445200, '445281', '普宁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445300, 440000, '445300', '云浮市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445302, 445300, '445302', '云城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445303, 445300, '445303', '云安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445321, 445300, '445321', '新兴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445322, 445300, '445322', '郁南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (445381, 445300, '445381', '罗定市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450000, 86, '450000', '广西壮族自治区', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450100, 450000, '450100', '南宁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450102, 450100, '450102', '兴宁区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450103, 450100, '450103', '青秀区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450105, 450100, '450105', '江南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450107, 450100, '450107', '西乡塘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450108, 450100, '450108', '良庆区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450109, 450100, '450109', '邕宁区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450110, 450100, '450110', '武鸣区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450123, 450100, '450123', '隆安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450124, 450100, '450124', '马山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450125, 450100, '450125', '上林县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450126, 450100, '450126', '宾阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450127, 450100, '450127', '横县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450200, 450000, '450200', '柳州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450202, 450200, '450202', '城中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450203, 450200, '450203', '鱼峰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450204, 450200, '450204', '柳南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450205, 450200, '450205', '柳北区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450206, 450200, '450206', '柳江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450222, 450200, '450222', '柳城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450223, 450200, '450223', '鹿寨县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450224, 450200, '450224', '融安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450225, 450200, '450225', '融水苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450226, 450200, '450226', '三江侗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450300, 450000, '450300', '桂林市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450302, 450300, '450302', '秀峰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450303, 450300, '450303', '叠彩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450304, 450300, '450304', '象山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450305, 450300, '450305', '七星区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450311, 450300, '450311', '雁山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450312, 450300, '450312', '临桂区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450321, 450300, '450321', '阳朔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450323, 450300, '450323', '灵川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450324, 450300, '450324', '全州县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450325, 450300, '450325', '兴安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450326, 450300, '450326', '永福县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450327, 450300, '450327', '灌阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450328, 450300, '450328', '龙胜各族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450329, 450300, '450329', '资源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450330, 450300, '450330', '平乐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450332, 450300, '450332', '恭城瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450381, 450300, '450381', '荔浦市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450400, 450000, '450400', '梧州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450403, 450400, '450403', '万秀区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450405, 450400, '450405', '长洲区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450406, 450400, '450406', '龙圩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450421, 450400, '450421', '苍梧县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450422, 450400, '450422', '藤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450423, 450400, '450423', '蒙山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450481, 450400, '450481', '岑溪市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450500, 450000, '450500', '北海市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450502, 450500, '450502', '海城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450503, 450500, '450503', '银海区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450512, 450500, '450512', '铁山港区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450521, 450500, '450521', '合浦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450600, 450000, '450600', '防城港市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450602, 450600, '450602', '港口区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450603, 450600, '450603', '防城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450621, 450600, '450621', '上思县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450681, 450600, '450681', '东兴市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450700, 450000, '450700', '钦州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450702, 450700, '450702', '钦南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450703, 450700, '450703', '钦北区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450721, 450700, '450721', '灵山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450722, 450700, '450722', '浦北县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450800, 450000, '450800', '贵港市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450802, 450800, '450802', '港北区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450803, 450800, '450803', '港南区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450804, 450800, '450804', '覃塘区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450821, 450800, '450821', '平南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450881, 450800, '450881', '桂平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450900, 450000, '450900', '玉林市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450902, 450900, '450902', '玉州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450903, 450900, '450903', '福绵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450921, 450900, '450921', '容县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450922, 450900, '450922', '陆川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450923, 450900, '450923', '博白县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450924, 450900, '450924', '兴业县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (450981, 450900, '450981', '北流市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451000, 450000, '451000', '百色市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451002, 451000, '451002', '右江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451003, 451000, '451003', '田阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451022, 451000, '451022', '田东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451024, 451000, '451024', '德保县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451026, 451000, '451026', '那坡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451027, 451000, '451027', '凌云县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451028, 451000, '451028', '乐业县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451029, 451000, '451029', '田林县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451030, 451000, '451030', '西林县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451031, 451000, '451031', '隆林各族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451081, 451000, '451081', '靖西市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451082, 451000, '451082', '平果市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451100, 450000, '451100', '贺州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451102, 451100, '451102', '八步区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451103, 451100, '451103', '平桂区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451121, 451100, '451121', '昭平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451122, 451100, '451122', '钟山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451123, 451100, '451123', '富川瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451200, 450000, '451200', '河池市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451202, 451200, '451202', '金城江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451203, 451200, '451203', '宜州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451221, 451200, '451221', '南丹县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451222, 451200, '451222', '天峨县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451223, 451200, '451223', '凤山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451224, 451200, '451224', '东兰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451225, 451200, '451225', '罗城仫佬族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451226, 451200, '451226', '环江毛南族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451227, 451200, '451227', '巴马瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451228, 451200, '451228', '都安瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451229, 451200, '451229', '大化瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451300, 450000, '451300', '来宾市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451302, 451300, '451302', '兴宾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451321, 451300, '451321', '忻城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451322, 451300, '451322', '象州县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451323, 451300, '451323', '武宣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451324, 451300, '451324', '金秀瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451381, 451300, '451381', '合山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451400, 450000, '451400', '崇左市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451402, 451400, '451402', '江州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451421, 451400, '451421', '扶绥县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451422, 451400, '451422', '宁明县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451423, 451400, '451423', '龙州县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451424, 451400, '451424', '大新县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451425, 451400, '451425', '天等县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (451481, 451400, '451481', '凭祥市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460000, 86, '460000', '海南省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460100, 460000, '460100', '海口市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460105, 460100, '460105', '秀英区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460106, 460100, '460106', '龙华区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460107, 460100, '460107', '琼山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460108, 460100, '460108', '美兰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460200, 460000, '460200', '三亚市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460202, 460200, '460202', '海棠区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460203, 460200, '460203', '吉阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460204, 460200, '460204', '天涯区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460205, 460200, '460205', '崖州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460300, 460000, '460300', '三沙市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (460400, 460000, '460400', '儋州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469001, 460000, '469001', '五指山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469002, 460000, '469002', '琼海市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469005, 460000, '469005', '文昌市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469006, 460000, '469006', '万宁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469007, 460000, '469007', '东方市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469021, 460000, '469021', '定安县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469022, 460000, '469022', '屯昌县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469023, 460000, '469023', '澄迈县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469024, 460000, '469024', '临高县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469025, 460000, '469025', '白沙黎族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469026, 460000, '469026', '昌江黎族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469027, 460000, '469027', '乐东黎族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469028, 460000, '469028', '陵水黎族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469029, 460000, '469029', '保亭黎族苗族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (469030, 460000, '469030', '琼中黎族苗族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500000, 86, '500000', '重庆市', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500101, 500000, '500101', '万州区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500102, 500000, '500102', '涪陵区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500103, 500000, '500103', '渝中区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500104, 500000, '500104', '大渡口区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500105, 500000, '500105', '江北区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500106, 500000, '500106', '沙坪坝区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500107, 500000, '500107', '九龙坡区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500108, 500000, '500108', '南岸区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500109, 500000, '500109', '北碚区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500110, 500000, '500110', '綦江区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500111, 500000, '500111', '大足区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500112, 500000, '500112', '渝北区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500113, 500000, '500113', '巴南区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500114, 500000, '500114', '黔江区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500115, 500000, '500115', '长寿区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500116, 500000, '500116', '江津区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500117, 500000, '500117', '合川区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500118, 500000, '500118', '永川区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500119, 500000, '500119', '南川区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500120, 500000, '500120', '璧山区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500151, 500000, '500151', '铜梁区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500152, 500000, '500152', '潼南区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500153, 500000, '500153', '荣昌区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500154, 500000, '500154', '开州区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500155, 500000, '500155', '梁平区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500156, 500000, '500156', '武隆区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500229, 500000, '500229', '城口县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500230, 500000, '500230', '丰都县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500231, 500000, '500231', '垫江县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500233, 500000, '500233', '忠县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500235, 500000, '500235', '云阳县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500236, 500000, '500236', '奉节县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500237, 500000, '500237', '巫山县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500238, 500000, '500238', '巫溪县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500240, 500000, '500240', '石柱土家族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500241, 500000, '500241', '秀山土家族苗族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500242, 500000, '500242', '酉阳土家族苗族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (500243, 500000, '500243', '彭水苗族土家族自治县', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510000, 86, '510000', '四川省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510100, 510000, '510100', '成都市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510104, 510100, '510104', '锦江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510105, 510100, '510105', '青羊区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510106, 510100, '510106', '金牛区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510107, 510100, '510107', '武侯区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510108, 510100, '510108', '成华区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510112, 510100, '510112', '龙泉驿区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510113, 510100, '510113', '青白江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510114, 510100, '510114', '新都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510115, 510100, '510115', '温江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510116, 510100, '510116', '双流区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510117, 510100, '510117', '郫都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510118, 510100, '510118', '新津区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510121, 510100, '510121', '金堂县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510129, 510100, '510129', '大邑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510131, 510100, '510131', '蒲江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510181, 510100, '510181', '都江堰市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510182, 510100, '510182', '彭州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510183, 510100, '510183', '邛崃市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510184, 510100, '510184', '崇州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510185, 510100, '510185', '简阳市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510300, 510000, '510300', '自贡市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510302, 510300, '510302', '自流井区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510303, 510300, '510303', '贡井区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510304, 510300, '510304', '大安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510311, 510300, '510311', '沿滩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510321, 510300, '510321', '荣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510322, 510300, '510322', '富顺县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510400, 510000, '510400', '攀枝花市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510402, 510400, '510402', '东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510403, 510400, '510403', '西区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510411, 510400, '510411', '仁和区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510421, 510400, '510421', '米易县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510422, 510400, '510422', '盐边县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510500, 510000, '510500', '泸州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510502, 510500, '510502', '江阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510503, 510500, '510503', '纳溪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510504, 510500, '510504', '龙马潭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510521, 510500, '510521', '泸县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510522, 510500, '510522', '合江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510524, 510500, '510524', '叙永县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510525, 510500, '510525', '古蔺县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510600, 510000, '510600', '德阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510603, 510600, '510603', '旌阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510604, 510600, '510604', '罗江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510623, 510600, '510623', '中江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510681, 510600, '510681', '广汉市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510682, 510600, '510682', '什邡市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510683, 510600, '510683', '绵竹市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510700, 510000, '510700', '绵阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510703, 510700, '510703', '涪城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510704, 510700, '510704', '游仙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510705, 510700, '510705', '安州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510722, 510700, '510722', '三台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510723, 510700, '510723', '盐亭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510725, 510700, '510725', '梓潼县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510726, 510700, '510726', '北川羌族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510727, 510700, '510727', '平武县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510781, 510700, '510781', '江油市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510800, 510000, '510800', '广元市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510802, 510800, '510802', '利州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510811, 510800, '510811', '昭化区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510812, 510800, '510812', '朝天区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510821, 510800, '510821', '旺苍县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510822, 510800, '510822', '青川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510823, 510800, '510823', '剑阁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510824, 510800, '510824', '苍溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510900, 510000, '510900', '遂宁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510903, 510900, '510903', '船山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510904, 510900, '510904', '安居区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510921, 510900, '510921', '蓬溪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510923, 510900, '510923', '大英县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (510981, 510900, '510981', '射洪市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511000, 510000, '511000', '内江市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511002, 511000, '511002', '市中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511011, 511000, '511011', '东兴区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511024, 511000, '511024', '威远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511025, 511000, '511025', '资中县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511083, 511000, '511083', '隆昌市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511100, 510000, '511100', '乐山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511102, 511100, '511102', '市中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511111, 511100, '511111', '沙湾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511112, 511100, '511112', '五通桥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511113, 511100, '511113', '金口河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511123, 511100, '511123', '犍为县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511124, 511100, '511124', '井研县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511126, 511100, '511126', '夹江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511129, 511100, '511129', '沐川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511132, 511100, '511132', '峨边彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511133, 511100, '511133', '马边彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511181, 511100, '511181', '峨眉山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511300, 510000, '511300', '南充市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511302, 511300, '511302', '顺庆区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511303, 511300, '511303', '高坪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511304, 511300, '511304', '嘉陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511321, 511300, '511321', '南部县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511322, 511300, '511322', '营山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511323, 511300, '511323', '蓬安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511324, 511300, '511324', '仪陇县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511325, 511300, '511325', '西充县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511381, 511300, '511381', '阆中市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511400, 510000, '511400', '眉山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511402, 511400, '511402', '东坡区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511403, 511400, '511403', '彭山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511421, 511400, '511421', '仁寿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511423, 511400, '511423', '洪雅县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511424, 511400, '511424', '丹棱县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511425, 511400, '511425', '青神县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511500, 510000, '511500', '宜宾市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511502, 511500, '511502', '翠屏区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511503, 511500, '511503', '南溪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511504, 511500, '511504', '叙州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511523, 511500, '511523', '江安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511524, 511500, '511524', '长宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511525, 511500, '511525', '高县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511526, 511500, '511526', '珙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511527, 511500, '511527', '筠连县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511528, 511500, '511528', '兴文县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511529, 511500, '511529', '屏山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511600, 510000, '511600', '广安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511602, 511600, '511602', '广安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511603, 511600, '511603', '前锋区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511621, 511600, '511621', '岳池县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511622, 511600, '511622', '武胜县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511623, 511600, '511623', '邻水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511681, 511600, '511681', '华蓥市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511700, 510000, '511700', '达州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511702, 511700, '511702', '通川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511703, 511700, '511703', '达川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511722, 511700, '511722', '宣汉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511723, 511700, '511723', '开江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511724, 511700, '511724', '大竹县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511725, 511700, '511725', '渠县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511781, 511700, '511781', '万源市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511800, 510000, '511800', '雅安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511802, 511800, '511802', '雨城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511803, 511800, '511803', '名山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511822, 511800, '511822', '荥经县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511823, 511800, '511823', '汉源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511824, 511800, '511824', '石棉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511825, 511800, '511825', '天全县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511826, 511800, '511826', '芦山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511827, 511800, '511827', '宝兴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511900, 510000, '511900', '巴中市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511902, 511900, '511902', '巴州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511903, 511900, '511903', '恩阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511921, 511900, '511921', '通江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511922, 511900, '511922', '南江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (511923, 511900, '511923', '平昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (512000, 510000, '512000', '资阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (512002, 512000, '512002', '雁江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (512021, 512000, '512021', '安岳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (512022, 512000, '512022', '乐至县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513200, 510000, '513200', '阿坝藏族羌族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513201, 513200, '513201', '马尔康市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513221, 513200, '513221', '汶川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513222, 513200, '513222', '理县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513223, 513200, '513223', '茂县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513224, 513200, '513224', '松潘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513225, 513200, '513225', '九寨沟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513226, 513200, '513226', '金川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513227, 513200, '513227', '小金县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513228, 513200, '513228', '黑水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513230, 513200, '513230', '壤塘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513231, 513200, '513231', '阿坝县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513232, 513200, '513232', '若尔盖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513233, 513200, '513233', '红原县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513300, 510000, '513300', '甘孜藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513301, 513300, '513301', '康定市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513322, 513300, '513322', '泸定县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513323, 513300, '513323', '丹巴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513324, 513300, '513324', '九龙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513325, 513300, '513325', '雅江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513326, 513300, '513326', '道孚县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513327, 513300, '513327', '炉霍县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513328, 513300, '513328', '甘孜县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513329, 513300, '513329', '新龙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513330, 513300, '513330', '德格县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513331, 513300, '513331', '白玉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513332, 513300, '513332', '石渠县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513333, 513300, '513333', '色达县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513334, 513300, '513334', '理塘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513335, 513300, '513335', '巴塘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513336, 513300, '513336', '乡城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513337, 513300, '513337', '稻城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513338, 513300, '513338', '得荣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513400, 510000, '513400', '凉山彝族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513401, 513400, '513401', '西昌市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513422, 513400, '513422', '木里藏族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513423, 513400, '513423', '盐源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513424, 513400, '513424', '德昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513425, 513400, '513425', '会理县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513426, 513400, '513426', '会东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513427, 513400, '513427', '宁南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513428, 513400, '513428', '普格县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513429, 513400, '513429', '布拖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513430, 513400, '513430', '金阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513431, 513400, '513431', '昭觉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513432, 513400, '513432', '喜德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513433, 513400, '513433', '冕宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513434, 513400, '513434', '越西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513435, 513400, '513435', '甘洛县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513436, 513400, '513436', '美姑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (513437, 513400, '513437', '雷波县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520000, 86, '520000', '贵州省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520100, 520000, '520100', '贵阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520102, 520100, '520102', '南明区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520103, 520100, '520103', '云岩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520111, 520100, '520111', '花溪区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520112, 520100, '520112', '乌当区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520113, 520100, '520113', '白云区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520115, 520100, '520115', '观山湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520121, 520100, '520121', '开阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520122, 520100, '520122', '息烽县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520123, 520100, '520123', '修文县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520181, 520100, '520181', '清镇市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520200, 520000, '520200', '六盘水市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520201, 520200, '520201', '钟山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520203, 520200, '520203', '六枝特区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520221, 520200, '520221', '水城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520281, 520200, '520281', '盘州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520300, 520000, '520300', '遵义市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520302, 520300, '520302', '红花岗区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520303, 520300, '520303', '汇川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520304, 520300, '520304', '播州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520322, 520300, '520322', '桐梓县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520323, 520300, '520323', '绥阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520324, 520300, '520324', '正安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520325, 520300, '520325', '道真仡佬族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520326, 520300, '520326', '务川仡佬族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520327, 520300, '520327', '凤冈县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520328, 520300, '520328', '湄潭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520329, 520300, '520329', '余庆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520330, 520300, '520330', '习水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520381, 520300, '520381', '赤水市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520382, 520300, '520382', '仁怀市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520400, 520000, '520400', '安顺市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520402, 520400, '520402', '西秀区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520403, 520400, '520403', '平坝区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520422, 520400, '520422', '普定县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520423, 520400, '520423', '镇宁布依族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520424, 520400, '520424', '关岭布依族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520425, 520400, '520425', '紫云苗族布依族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520500, 520000, '520500', '毕节市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520502, 520500, '520502', '七星关区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520521, 520500, '520521', '大方县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520522, 520500, '520522', '黔西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520523, 520500, '520523', '金沙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520524, 520500, '520524', '织金县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520525, 520500, '520525', '纳雍县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520526, 520500, '520526', '威宁彝族回族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520527, 520500, '520527', '赫章县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520600, 520000, '520600', '铜仁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520602, 520600, '520602', '碧江区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520603, 520600, '520603', '万山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520621, 520600, '520621', '江口县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520622, 520600, '520622', '玉屏侗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520623, 520600, '520623', '石阡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520624, 520600, '520624', '思南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520625, 520600, '520625', '印江土家族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520626, 520600, '520626', '德江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520627, 520600, '520627', '沿河土家族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (520628, 520600, '520628', '松桃苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522300, 520000, '522300', '黔西南布依族苗族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522301, 522300, '522301', '兴义市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522302, 522300, '522302', '兴仁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522323, 522300, '522323', '普安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522324, 522300, '522324', '晴隆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522325, 522300, '522325', '贞丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522326, 522300, '522326', '望谟县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522327, 522300, '522327', '册亨县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522328, 522300, '522328', '安龙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522600, 520000, '522600', '黔东南苗族侗族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522601, 522600, '522601', '凯里市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522622, 522600, '522622', '黄平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522623, 522600, '522623', '施秉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522624, 522600, '522624', '三穗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522625, 522600, '522625', '镇远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522626, 522600, '522626', '岑巩县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522627, 522600, '522627', '天柱县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522628, 522600, '522628', '锦屏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522629, 522600, '522629', '剑河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522630, 522600, '522630', '台江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522631, 522600, '522631', '黎平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522632, 522600, '522632', '榕江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522633, 522600, '522633', '从江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522634, 522600, '522634', '雷山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522635, 522600, '522635', '麻江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522636, 522600, '522636', '丹寨县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522700, 520000, '522700', '黔南布依族苗族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522701, 522700, '522701', '都匀市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522702, 522700, '522702', '福泉市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522722, 522700, '522722', '荔波县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522723, 522700, '522723', '贵定县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522725, 522700, '522725', '瓮安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522726, 522700, '522726', '独山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522727, 522700, '522727', '平塘县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522728, 522700, '522728', '罗甸县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522729, 522700, '522729', '长顺县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522730, 522700, '522730', '龙里县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522731, 522700, '522731', '惠水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (522732, 522700, '522732', '三都水族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530000, 86, '530000', '云南省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530100, 530000, '530100', '昆明市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530102, 530100, '530102', '五华区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530103, 530100, '530103', '盘龙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530111, 530100, '530111', '官渡区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530112, 530100, '530112', '西山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530113, 530100, '530113', '东川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530114, 530100, '530114', '呈贡区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530115, 530100, '530115', '晋宁区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530124, 530100, '530124', '富民县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530125, 530100, '530125', '宜良县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530126, 530100, '530126', '石林彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530127, 530100, '530127', '嵩明县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530128, 530100, '530128', '禄劝彝族苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530129, 530100, '530129', '寻甸回族彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530181, 530100, '530181', '安宁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530300, 530000, '530300', '曲靖市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530302, 530300, '530302', '麒麟区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530303, 530300, '530303', '沾益区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530304, 530300, '530304', '马龙区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530322, 530300, '530322', '陆良县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530323, 530300, '530323', '师宗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530324, 530300, '530324', '罗平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530325, 530300, '530325', '富源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530326, 530300, '530326', '会泽县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530381, 530300, '530381', '宣威市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530400, 530000, '530400', '玉溪市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530402, 530400, '530402', '红塔区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530403, 530400, '530403', '江川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530423, 530400, '530423', '通海县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530424, 530400, '530424', '华宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530425, 530400, '530425', '易门县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530426, 530400, '530426', '峨山彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530427, 530400, '530427', '新平彝族傣族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530428, 530400, '530428', '元江哈尼族彝族傣族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530481, 530400, '530481', '澄江市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530500, 530000, '530500', '保山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530502, 530500, '530502', '隆阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530521, 530500, '530521', '施甸县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530523, 530500, '530523', '龙陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530524, 530500, '530524', '昌宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530581, 530500, '530581', '腾冲市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530600, 530000, '530600', '昭通市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530602, 530600, '530602', '昭阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530621, 530600, '530621', '鲁甸县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530622, 530600, '530622', '巧家县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530623, 530600, '530623', '盐津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530624, 530600, '530624', '大关县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530625, 530600, '530625', '永善县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530626, 530600, '530626', '绥江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530627, 530600, '530627', '镇雄县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530628, 530600, '530628', '彝良县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530629, 530600, '530629', '威信县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530681, 530600, '530681', '水富市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530700, 530000, '530700', '丽江市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530702, 530700, '530702', '古城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530721, 530700, '530721', '玉龙纳西族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530722, 530700, '530722', '永胜县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530723, 530700, '530723', '华坪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530724, 530700, '530724', '宁蒗彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530800, 530000, '530800', '普洱市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530802, 530800, '530802', '思茅区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530821, 530800, '530821', '宁洱哈尼族彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530822, 530800, '530822', '墨江哈尼族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530823, 530800, '530823', '景东彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530824, 530800, '530824', '景谷傣族彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530825, 530800, '530825', '镇沅彝族哈尼族拉祜族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530826, 530800, '530826', '江城哈尼族彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530827, 530800, '530827', '孟连傣族拉祜族佤族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530828, 530800, '530828', '澜沧拉祜族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530829, 530800, '530829', '西盟佤族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530900, 530000, '530900', '临沧市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530902, 530900, '530902', '临翔区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530921, 530900, '530921', '凤庆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530922, 530900, '530922', '云县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530923, 530900, '530923', '永德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530924, 530900, '530924', '镇康县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530925, 530900, '530925', '双江拉祜族佤族布朗族傣族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530926, 530900, '530926', '耿马傣族佤族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (530927, 530900, '530927', '沧源佤族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532300, 530000, '532300', '楚雄彝族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532301, 532300, '532301', '楚雄市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532322, 532300, '532322', '双柏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532323, 532300, '532323', '牟定县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532324, 532300, '532324', '南华县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532325, 532300, '532325', '姚安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532326, 532300, '532326', '大姚县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532327, 532300, '532327', '永仁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532328, 532300, '532328', '元谋县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532329, 532300, '532329', '武定县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532331, 532300, '532331', '禄丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532500, 530000, '532500', '红河哈尼族彝族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532501, 532500, '532501', '个旧市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532502, 532500, '532502', '开远市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532503, 532500, '532503', '蒙自市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532504, 532500, '532504', '弥勒市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532523, 532500, '532523', '屏边苗族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532524, 532500, '532524', '建水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532525, 532500, '532525', '石屏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532527, 532500, '532527', '泸西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532528, 532500, '532528', '元阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532529, 532500, '532529', '红河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532530, 532500, '532530', '金平苗族瑶族傣族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532531, 532500, '532531', '绿春县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532532, 532500, '532532', '河口瑶族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532600, 530000, '532600', '文山壮族苗族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532601, 532600, '532601', '文山市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532622, 532600, '532622', '砚山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532623, 532600, '532623', '西畴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532624, 532600, '532624', '麻栗坡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532625, 532600, '532625', '马关县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532626, 532600, '532626', '丘北县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532627, 532600, '532627', '广南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532628, 532600, '532628', '富宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532800, 530000, '532800', '西双版纳傣族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532801, 532800, '532801', '景洪市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532822, 532800, '532822', '勐海县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532823, 532800, '532823', '勐腊县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532900, 530000, '532900', '大理白族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532901, 532900, '532901', '大理市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532922, 532900, '532922', '漾濞彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532923, 532900, '532923', '祥云县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532924, 532900, '532924', '宾川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532925, 532900, '532925', '弥渡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532926, 532900, '532926', '南涧彝族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532927, 532900, '532927', '巍山彝族回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532928, 532900, '532928', '永平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532929, 532900, '532929', '云龙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532930, 532900, '532930', '洱源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532931, 532900, '532931', '剑川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (532932, 532900, '532932', '鹤庆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533100, 530000, '533100', '德宏傣族景颇族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533102, 533100, '533102', '瑞丽市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533103, 533100, '533103', '芒市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533122, 533100, '533122', '梁河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533123, 533100, '533123', '盈江县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533124, 533100, '533124', '陇川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533300, 530000, '533300', '怒江傈僳族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533301, 533300, '533301', '泸水市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533323, 533300, '533323', '福贡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533324, 533300, '533324', '贡山独龙族怒族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533325, 533300, '533325', '兰坪白族普米族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533400, 530000, '533400', '迪庆藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533401, 533400, '533401', '香格里拉市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533422, 533400, '533422', '德钦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (533423, 533400, '533423', '维西傈僳族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540000, 86, '540000', '西藏自治区', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540100, 540000, '540100', '拉萨市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540102, 540100, '540102', '城关区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540103, 540100, '540103', '堆龙德庆区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540104, 540100, '540104', '达孜区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540121, 540100, '540121', '林周县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540122, 540100, '540122', '当雄县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540123, 540100, '540123', '尼木县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540124, 540100, '540124', '曲水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540127, 540100, '540127', '墨竹工卡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540200, 540000, '540200', '日喀则市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540202, 540200, '540202', '桑珠孜区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540221, 540200, '540221', '南木林县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540222, 540200, '540222', '江孜县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540223, 540200, '540223', '定日县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540224, 540200, '540224', '萨迦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540225, 540200, '540225', '拉孜县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540226, 540200, '540226', '昂仁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540227, 540200, '540227', '谢通门县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540228, 540200, '540228', '白朗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540229, 540200, '540229', '仁布县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540230, 540200, '540230', '康马县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540231, 540200, '540231', '定结县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540232, 540200, '540232', '仲巴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540233, 540200, '540233', '亚东县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540234, 540200, '540234', '吉隆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540235, 540200, '540235', '聂拉木县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540236, 540200, '540236', '萨嘎县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540237, 540200, '540237', '岗巴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540300, 540000, '540300', '昌都市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540302, 540300, '540302', '卡若区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540321, 540300, '540321', '江达县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540322, 540300, '540322', '贡觉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540323, 540300, '540323', '类乌齐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540324, 540300, '540324', '丁青县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540325, 540300, '540325', '察雅县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540326, 540300, '540326', '八宿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540327, 540300, '540327', '左贡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540328, 540300, '540328', '芒康县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540329, 540300, '540329', '洛隆县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540330, 540300, '540330', '边坝县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540400, 540000, '540400', '林芝市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540402, 540400, '540402', '巴宜区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540421, 540400, '540421', '工布江达县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540422, 540400, '540422', '米林县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540423, 540400, '540423', '墨脱县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540424, 540400, '540424', '波密县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540425, 540400, '540425', '察隅县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540426, 540400, '540426', '朗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540500, 540000, '540500', '山南市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540502, 540500, '540502', '乃东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540521, 540500, '540521', '扎囊县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540522, 540500, '540522', '贡嘎县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540523, 540500, '540523', '桑日县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540524, 540500, '540524', '琼结县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540525, 540500, '540525', '曲松县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540526, 540500, '540526', '措美县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540527, 540500, '540527', '洛扎县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540528, 540500, '540528', '加查县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540529, 540500, '540529', '隆子县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540530, 540500, '540530', '错那县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540531, 540500, '540531', '浪卡子县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540600, 540000, '540600', '那曲市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540602, 540600, '540602', '色尼区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540621, 540600, '540621', '嘉黎县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540622, 540600, '540622', '比如县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540623, 540600, '540623', '聂荣县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540624, 540600, '540624', '安多县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540625, 540600, '540625', '申扎县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540626, 540600, '540626', '索县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540627, 540600, '540627', '班戈县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540628, 540600, '540628', '巴青县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540629, 540600, '540629', '尼玛县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (540630, 540600, '540630', '双湖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542500, 540000, '542500', '阿里地区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542521, 542500, '542521', '普兰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542522, 542500, '542522', '札达县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542523, 542500, '542523', '噶尔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542524, 542500, '542524', '日土县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542525, 542500, '542525', '革吉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542526, 542500, '542526', '改则县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (542527, 542500, '542527', '措勤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610000, 86, '610000', '陕西省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610100, 610000, '610100', '西安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610102, 610100, '610102', '新城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610103, 610100, '610103', '碑林区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610104, 610100, '610104', '莲湖区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610111, 610100, '610111', '灞桥区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610112, 610100, '610112', '未央区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610113, 610100, '610113', '雁塔区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610114, 610100, '610114', '阎良区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610115, 610100, '610115', '临潼区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610116, 610100, '610116', '长安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610117, 610100, '610117', '高陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610118, 610100, '610118', '鄠邑区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610122, 610100, '610122', '蓝田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610124, 610100, '610124', '周至县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610200, 610000, '610200', '铜川市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610202, 610200, '610202', '王益区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610203, 610200, '610203', '印台区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610204, 610200, '610204', '耀州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610222, 610200, '610222', '宜君县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610300, 610000, '610300', '宝鸡市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610302, 610300, '610302', '渭滨区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610303, 610300, '610303', '金台区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610304, 610300, '610304', '陈仓区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610322, 610300, '610322', '凤翔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610323, 610300, '610323', '岐山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610324, 610300, '610324', '扶风县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610326, 610300, '610326', '眉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610327, 610300, '610327', '陇县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610328, 610300, '610328', '千阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610329, 610300, '610329', '麟游县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610330, 610300, '610330', '凤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610331, 610300, '610331', '太白县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610400, 610000, '610400', '咸阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610402, 610400, '610402', '秦都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610403, 610400, '610403', '杨陵区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610404, 610400, '610404', '渭城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610422, 610400, '610422', '三原县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610423, 610400, '610423', '泾阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610424, 610400, '610424', '乾县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610425, 610400, '610425', '礼泉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610426, 610400, '610426', '永寿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610428, 610400, '610428', '长武县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610429, 610400, '610429', '旬邑县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610430, 610400, '610430', '淳化县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610431, 610400, '610431', '武功县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610481, 610400, '610481', '兴平市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610482, 610400, '610482', '彬州市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610500, 610000, '610500', '渭南市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610502, 610500, '610502', '临渭区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610503, 610500, '610503', '华州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610522, 610500, '610522', '潼关县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610523, 610500, '610523', '大荔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610524, 610500, '610524', '合阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610525, 610500, '610525', '澄城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610526, 610500, '610526', '蒲城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610527, 610500, '610527', '白水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610528, 610500, '610528', '富平县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610581, 610500, '610581', '韩城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610582, 610500, '610582', '华阴市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610600, 610000, '610600', '延安市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610602, 610600, '610602', '宝塔区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610603, 610600, '610603', '安塞区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610621, 610600, '610621', '延长县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610622, 610600, '610622', '延川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610625, 610600, '610625', '志丹县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610626, 610600, '610626', '吴起县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610627, 610600, '610627', '甘泉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610628, 610600, '610628', '富县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610629, 610600, '610629', '洛川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610630, 610600, '610630', '宜川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610631, 610600, '610631', '黄龙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610632, 610600, '610632', '黄陵县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610681, 610600, '610681', '子长市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610700, 610000, '610700', '汉中市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610702, 610700, '610702', '汉台区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610703, 610700, '610703', '南郑区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610722, 610700, '610722', '城固县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610723, 610700, '610723', '洋县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610724, 610700, '610724', '西乡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610725, 610700, '610725', '勉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610726, 610700, '610726', '宁强县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610727, 610700, '610727', '略阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610728, 610700, '610728', '镇巴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610729, 610700, '610729', '留坝县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610730, 610700, '610730', '佛坪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610800, 610000, '610800', '榆林市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610802, 610800, '610802', '榆阳区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610803, 610800, '610803', '横山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610822, 610800, '610822', '府谷县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610824, 610800, '610824', '靖边县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610825, 610800, '610825', '定边县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610826, 610800, '610826', '绥德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610827, 610800, '610827', '米脂县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610828, 610800, '610828', '佳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610829, 610800, '610829', '吴堡县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610830, 610800, '610830', '清涧县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610831, 610800, '610831', '子洲县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610881, 610800, '610881', '神木市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610900, 610000, '610900', '安康市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610902, 610900, '610902', '汉滨区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610921, 610900, '610921', '汉阴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610922, 610900, '610922', '石泉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610923, 610900, '610923', '宁陕县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610924, 610900, '610924', '紫阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610925, 610900, '610925', '岚皋县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610926, 610900, '610926', '平利县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610927, 610900, '610927', '镇坪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610928, 610900, '610928', '旬阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (610929, 610900, '610929', '白河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611000, 610000, '611000', '商洛市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611002, 611000, '611002', '商州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611021, 611000, '611021', '洛南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611022, 611000, '611022', '丹凤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611023, 611000, '611023', '商南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611024, 611000, '611024', '山阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611025, 611000, '611025', '镇安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (611026, 611000, '611026', '柞水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620000, 86, '620000', '甘肃省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620100, 620000, '620100', '兰州市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620102, 620100, '620102', '城关区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620103, 620100, '620103', '七里河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620104, 620100, '620104', '西固区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620105, 620100, '620105', '安宁区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620111, 620100, '620111', '红古区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620121, 620100, '620121', '永登县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620122, 620100, '620122', '皋兰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620123, 620100, '620123', '榆中县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620200, 620000, '620200', '嘉峪关市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620300, 620000, '620300', '金昌市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620302, 620300, '620302', '金川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620321, 620300, '620321', '永昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620400, 620000, '620400', '白银市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620402, 620400, '620402', '白银区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620403, 620400, '620403', '平川区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620421, 620400, '620421', '靖远县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620422, 620400, '620422', '会宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620423, 620400, '620423', '景泰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620500, 620000, '620500', '天水市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620502, 620500, '620502', '秦州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620503, 620500, '620503', '麦积区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620521, 620500, '620521', '清水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620522, 620500, '620522', '秦安县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620523, 620500, '620523', '甘谷县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620524, 620500, '620524', '武山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620525, 620500, '620525', '张家川回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620600, 620000, '620600', '武威市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620602, 620600, '620602', '凉州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620621, 620600, '620621', '民勤县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620622, 620600, '620622', '古浪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620623, 620600, '620623', '天祝藏族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620700, 620000, '620700', '张掖市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620702, 620700, '620702', '甘州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620721, 620700, '620721', '肃南裕固族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620722, 620700, '620722', '民乐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620723, 620700, '620723', '临泽县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620724, 620700, '620724', '高台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620725, 620700, '620725', '山丹县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620800, 620000, '620800', '平凉市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620802, 620800, '620802', '崆峒区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620821, 620800, '620821', '泾川县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620822, 620800, '620822', '灵台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620823, 620800, '620823', '崇信县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620825, 620800, '620825', '庄浪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620826, 620800, '620826', '静宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620881, 620800, '620881', '华亭市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620900, 620000, '620900', '酒泉市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620902, 620900, '620902', '肃州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620921, 620900, '620921', '金塔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620922, 620900, '620922', '瓜州县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620923, 620900, '620923', '肃北蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620924, 620900, '620924', '阿克塞哈萨克族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620981, 620900, '620981', '玉门市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (620982, 620900, '620982', '敦煌市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621000, 620000, '621000', '庆阳市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621002, 621000, '621002', '西峰区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621021, 621000, '621021', '庆城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621022, 621000, '621022', '环县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621023, 621000, '621023', '华池县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621024, 621000, '621024', '合水县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621025, 621000, '621025', '正宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621026, 621000, '621026', '宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621027, 621000, '621027', '镇原县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621100, 620000, '621100', '定西市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621102, 621100, '621102', '安定区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621121, 621100, '621121', '通渭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621122, 621100, '621122', '陇西县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621123, 621100, '621123', '渭源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621124, 621100, '621124', '临洮县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621125, 621100, '621125', '漳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621126, 621100, '621126', '岷县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621200, 620000, '621200', '陇南市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621202, 621200, '621202', '武都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621221, 621200, '621221', '成县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621222, 621200, '621222', '文县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621223, 621200, '621223', '宕昌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621224, 621200, '621224', '康县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621225, 621200, '621225', '西和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621226, 621200, '621226', '礼县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621227, 621200, '621227', '徽县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (621228, 621200, '621228', '两当县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622900, 620000, '622900', '临夏回族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622901, 622900, '622901', '临夏市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622921, 622900, '622921', '临夏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622922, 622900, '622922', '康乐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622923, 622900, '622923', '永靖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622924, 622900, '622924', '广河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622925, 622900, '622925', '和政县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622926, 622900, '622926', '东乡族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (622927, 622900, '622927', '积石山保安族东乡族撒拉族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623000, 620000, '623000', '甘南藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623001, 623000, '623001', '合作市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623021, 623000, '623021', '临潭县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623022, 623000, '623022', '卓尼县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623023, 623000, '623023', '舟曲县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623024, 623000, '623024', '迭部县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623025, 623000, '623025', '玛曲县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623026, 623000, '623026', '碌曲县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (623027, 623000, '623027', '夏河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630000, 86, '630000', '青海省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630100, 630000, '630100', '西宁市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630102, 630100, '630102', '城东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630103, 630100, '630103', '城中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630104, 630100, '630104', '城西区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630105, 630100, '630105', '城北区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630106, 630100, '630106', '湟中区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630121, 630100, '630121', '大通回族土族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630123, 630100, '630123', '湟源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630200, 630000, '630200', '海东市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630202, 630200, '630202', '乐都区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630203, 630200, '630203', '平安区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630222, 630200, '630222', '民和回族土族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630223, 630200, '630223', '互助土族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630224, 630200, '630224', '化隆回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (630225, 630200, '630225', '循化撒拉族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632200, 630000, '632200', '海北藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632221, 632200, '632221', '门源回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632222, 632200, '632222', '祁连县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632223, 632200, '632223', '海晏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632224, 632200, '632224', '刚察县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632300, 630000, '632300', '黄南藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632301, 632300, '632301', '同仁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632322, 632300, '632322', '尖扎县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632323, 632300, '632323', '泽库县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632324, 632300, '632324', '河南蒙古族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632500, 630000, '632500', '海南藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632521, 632500, '632521', '共和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632522, 632500, '632522', '同德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632523, 632500, '632523', '贵德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632524, 632500, '632524', '兴海县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632525, 632500, '632525', '贵南县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632600, 630000, '632600', '果洛藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632621, 632600, '632621', '玛沁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632622, 632600, '632622', '班玛县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632623, 632600, '632623', '甘德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632624, 632600, '632624', '达日县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632625, 632600, '632625', '久治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632626, 632600, '632626', '玛多县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632700, 630000, '632700', '玉树藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632701, 632700, '632701', '玉树市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632722, 632700, '632722', '杂多县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632723, 632700, '632723', '称多县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632724, 632700, '632724', '治多县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632725, 632700, '632725', '囊谦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632726, 632700, '632726', '曲麻莱县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632800, 630000, '632800', '海西蒙古族藏族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632801, 632800, '632801', '格尔木市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632802, 632800, '632802', '德令哈市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632803, 632800, '632803', '茫崖市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632821, 632800, '632821', '乌兰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632822, 632800, '632822', '都兰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (632823, 632800, '632823', '天峻县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640000, 86, '640000', '宁夏回族自治区', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640100, 640000, '640100', '银川市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640104, 640100, '640104', '兴庆区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640105, 640100, '640105', '西夏区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640106, 640100, '640106', '金凤区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640121, 640100, '640121', '永宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640122, 640100, '640122', '贺兰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640181, 640100, '640181', '灵武市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640200, 640000, '640200', '石嘴山市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640202, 640200, '640202', '大武口区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640205, 640200, '640205', '惠农区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640221, 640200, '640221', '平罗县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640300, 640000, '640300', '吴忠市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640302, 640300, '640302', '利通区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640303, 640300, '640303', '红寺堡区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640323, 640300, '640323', '盐池县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640324, 640300, '640324', '同心县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640381, 640300, '640381', '青铜峡市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640400, 640000, '640400', '固原市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640402, 640400, '640402', '原州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640422, 640400, '640422', '西吉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640423, 640400, '640423', '隆德县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640424, 640400, '640424', '泾源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640425, 640400, '640425', '彭阳县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640500, 640000, '640500', '中卫市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640502, 640500, '640502', '沙坡头区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640521, 640500, '640521', '中宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (640522, 640500, '640522', '海原县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650000, 86, '650000', '新疆维吾尔自治区', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650100, 650000, '650100', '乌鲁木齐市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650102, 650100, '650102', '天山区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650103, 650100, '650103', '沙依巴克区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650104, 650100, '650104', '新市区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650105, 650100, '650105', '水磨沟区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650106, 650100, '650106', '头屯河区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650107, 650100, '650107', '达坂城区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650109, 650100, '650109', '米东区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650121, 650100, '650121', '乌鲁木齐县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650200, 650000, '650200', '克拉玛依市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650202, 650200, '650202', '独山子区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650203, 650200, '650203', '克拉玛依区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650204, 650200, '650204', '白碱滩区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650205, 650200, '650205', '乌尔禾区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650400, 650000, '650400', '吐鲁番市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650402, 650400, '650402', '高昌区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650421, 650400, '650421', '鄯善县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650422, 650400, '650422', '托克逊县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650500, 650000, '650500', '哈密市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650502, 650500, '650502', '伊州区', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650521, 650500, '650521', '巴里坤哈萨克自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (650522, 650500, '650522', '伊吾县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652300, 650000, '652300', '昌吉回族自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652301, 652300, '652301', '昌吉市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652302, 652300, '652302', '阜康市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652323, 652300, '652323', '呼图壁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652324, 652300, '652324', '玛纳斯县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652325, 652300, '652325', '奇台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652327, 652300, '652327', '吉木萨尔县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652328, 652300, '652328', '木垒哈萨克自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652700, 650000, '652700', '博尔塔拉蒙古自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652701, 652700, '652701', '博乐市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652702, 652700, '652702', '阿拉山口市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652722, 652700, '652722', '精河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652723, 652700, '652723', '温泉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652800, 650000, '652800', '巴音郭楞蒙古自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652801, 652800, '652801', '库尔勒市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652822, 652800, '652822', '轮台县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652823, 652800, '652823', '尉犁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652824, 652800, '652824', '若羌县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652825, 652800, '652825', '且末县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652826, 652800, '652826', '焉耆回族自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652827, 652800, '652827', '和静县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652828, 652800, '652828', '和硕县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652829, 652800, '652829', '博湖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652900, 650000, '652900', '阿克苏地区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652901, 652900, '652901', '阿克苏市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652902, 652900, '652902', '库车市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652922, 652900, '652922', '温宿县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652924, 652900, '652924', '沙雅县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652925, 652900, '652925', '新和县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652926, 652900, '652926', '拜城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652927, 652900, '652927', '乌什县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652928, 652900, '652928', '阿瓦提县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (652929, 652900, '652929', '柯坪县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653000, 650000, '653000', '克孜勒苏柯尔克孜自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653001, 653000, '653001', '阿图什市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653022, 653000, '653022', '阿克陶县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653023, 653000, '653023', '阿合奇县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653024, 653000, '653024', '乌恰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653100, 650000, '653100', '喀什地区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653101, 653100, '653101', '喀什市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653121, 653100, '653121', '疏附县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653122, 653100, '653122', '疏勒县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653123, 653100, '653123', '英吉沙县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653124, 653100, '653124', '泽普县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653125, 653100, '653125', '莎车县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653126, 653100, '653126', '叶城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653127, 653100, '653127', '麦盖提县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653128, 653100, '653128', '岳普湖县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653129, 653100, '653129', '伽师县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653130, 653100, '653130', '巴楚县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653131, 653100, '653131', '塔什库尔干塔吉克自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653200, 650000, '653200', '和田地区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653201, 653200, '653201', '和田市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653221, 653200, '653221', '和田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653222, 653200, '653222', '墨玉县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653223, 653200, '653223', '皮山县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653224, 653200, '653224', '洛浦县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653225, 653200, '653225', '策勒县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653226, 653200, '653226', '于田县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (653227, 653200, '653227', '民丰县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654000, 650000, '654000', '伊犁哈萨克自治州', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654002, 654000, '654002', '伊宁市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654003, 654000, '654003', '奎屯市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654004, 654000, '654004', '霍尔果斯市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654021, 654000, '654021', '伊宁县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654022, 654000, '654022', '察布查尔锡伯自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654023, 654000, '654023', '霍城县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654024, 654000, '654024', '巩留县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654025, 654000, '654025', '新源县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654026, 654000, '654026', '昭苏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654027, 654000, '654027', '特克斯县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654028, 654000, '654028', '尼勒克县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654200, 650000, '654200', '塔城地区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654201, 654200, '654201', '塔城市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654202, 654200, '654202', '乌苏市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654221, 654200, '654221', '额敏县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654223, 654200, '654223', '沙湾县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654224, 654200, '654224', '托里县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654225, 654200, '654225', '裕民县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654226, 654200, '654226', '和布克赛尔蒙古自治县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654300, 650000, '654300', '阿勒泰地区', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654301, 654300, '654301', '阿勒泰市', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654321, 654300, '654321', '布尔津县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654322, 654300, '654322', '富蕴县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654323, 654300, '654323', '福海县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654324, 654300, '654324', '哈巴河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654325, 654300, '654325', '青河县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (654326, 654300, '654326', '吉木乃县', 3, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659001, 650000, '659001', '石河子市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659002, 650000, '659002', '阿拉尔市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659003, 650000, '659003', '图木舒克市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659004, 650000, '659004', '五家渠市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659005, 650000, '659005', '北屯市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659006, 650000, '659006', '铁门关市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659007, 650000, '659007', '双河市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659008, 650000, '659008', '可克达拉市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659009, 650000, '659009', '昆玉市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (659010, 650000, '659010', '胡杨河市', 2, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (710000, 86, '710000', '台湾省', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (810000, 86, '810000', '香港特别行政区', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +INSERT INTO `sys_area` VALUES (820000, 86, '820000', '澳门特别行政区', 1, '0', 0, 1, '2020-12-28 17:43:31', 1, '2020-12-28 17:43:31', '2021-04-08 23:50:42'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_dict +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict`; +CREATE TABLE `sys_dict` ( + `id` bigint(19) NOT NULL COMMENT '字典主键', + `type_code` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典编号', + `type_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典名称', + `iz_lock` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否内置 0否 1是', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标记:0未删除,1删除', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` bigint(19) NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `type_code_typename_unique` (`type_code`,`type_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典表'; + +-- ---------------------------- +-- Records of sys_dict +-- ---------------------------- +BEGIN; +INSERT INTO `sys_dict` VALUES (1308396497528434689, '010110', '测试字典123', '1', '测试修改 - 123123', '1', 2, 1, '2020-09-22 08:23:28', 1, '2020-09-22 10:59:29', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1308782322607058946, 'test_type', '测试类型', '1', '测试类型', '0', 23, 1, '2020-09-23 09:56:36', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1314920925140922369, 'test', '测试', '0', NULL, '0', 3, 1313694379541635074, '2020-10-10 21:29:13', 1313694379541635074, '2020-10-10 21:57:32', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1314939057985335297, 'no_yes', '否是', '1', '用与 否是 判断', '0', 0, 1313694379541635074, '2020-10-10 22:41:16', 1313694379541635074, '2020-10-10 22:41:16', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1314939286306467841, 'menu_type', '菜单类型', '1', NULL, '0', 2, 1313694379541635074, '2020-10-10 22:42:11', 1, '2020-10-11 09:56:11', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1327879501833408513, 'table_type', '代码生成器v表类型', '1', '代码生成器', '0', 3, 1313694379541635074, '2020-11-15 15:41:59', 1, '2020-11-16 09:59:49', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1327979234979590146, 'jdbc_type', '代码生成器v数据库类型', '1', '代码生成器', '0', 1, 1313694379541635074, '2020-11-15 22:18:17', 1, '2020-11-16 09:59:45', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1328148882811367425, 'mysql_data_type', '代码生成器vMySQL数据类型', '1', '代码生成器\n', '0', 3, 1313694379541635074, '2020-11-16 09:32:24', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1328155300805324801, 'show_type', '代码生成器v显示类型', '1', '代码生成器\n', '0', 2, 1, '2020-11-16 09:57:54', 1, '2020-11-16 09:59:59', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1328591039258980353, 'validate_type', '代码生成器v验证类别', '1', '代码生成器', '0', 1, 1313694379541635074, '2020-11-17 14:49:22', 1, '2020-11-17 14:49:43', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1329005625682427905, 'java_data_type', '代码生成器vJava数据类型', '1', '代码生成器', '0', 1, 1313694379541635074, '2020-11-18 18:16:48', 1, '2020-11-18 18:17:09', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1330086884696694786, 'query_type', '代码生成器v检索类别', '1', '代码生成器', '0', 0, 1, '2020-11-21 17:53:20', 1, '2020-11-21 17:53:20', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1332662182483107842, 'org_type', '组织机构类型', '1', NULL, '0', 0, 1, '2020-11-28 20:26:39', 1, '2020-11-28 20:26:39', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1346735875094847489, '123123', '测试', '0', NULL, '1', 0, 1313694379541635074, '2021-01-06 16:30:28', 1313694379541635074, '2021-01-06 16:30:28', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1380172509525946369, 'crypto_asymmetric', '非对称加密', '1', NULL, '0', 0, 1313694379541635074, '2021-04-08 22:55:43', 1313694379541635074, '2021-04-08 22:55:43', '2021-04-08 23:50:52'); +INSERT INTO `sys_dict` VALUES (1388562098925977601, 'storage_type', '存储位置', '1', NULL, '0', 1, 1313694379541635074, '2021-05-02 02:32:57', 1, '2021-05-02 02:34:39', '2021-05-02 02:34:38'); +INSERT INTO `sys_dict` VALUES (1389291635615805442, 'password_level', '密码强度', '1', NULL, '0', 0, 1313694379541635074, '2021-05-04 02:51:52', 1313694379541635074, '2021-05-04 02:51:52', '2021-05-04 02:51:52'); +INSERT INTO `sys_dict` VALUES (1448557351479685121, 'role_data_scope', '角色数据范围', '1', NULL, '0', 0, 1, '2021-10-14 15:52:40', 1, '2021-10-14 15:52:40', '2021-10-14 15:50:56'); +INSERT INTO `sys_dict` VALUES (1463430609630846978, 'menu_role_label', '菜单角色类型标签', '1', NULL, '0', 0, 1, '2021-11-24 16:53:41', 1, '2021-11-24 16:53:41', '2021-11-24 16:51:41'); +INSERT INTO `sys_dict` VALUES (1551869799540985858, 'login_from', '登陆来源', '1', NULL, '0', 0, 1, '2022-07-26 17:59:27', 1, '2022-07-26 17:59:27', '2022-07-26 17:59:27'); +INSERT INTO `sys_dict` VALUES (1551894955382558721, 'log_type', '日志类型', '1', NULL, '0', 0, 1, '2022-07-26 19:39:25', 1, '2022-07-26 19:39:25', '2022-07-26 19:39:24'); +INSERT INTO `sys_dict` VALUES (1551895408610660353, 'log_level', '日志等级', '1', NULL, '0', 1, 1, '2022-07-26 19:41:13', 1, '2022-07-27 11:18:18', '2022-07-27 11:18:17'); +INSERT INTO `sys_dict` VALUES (1551896061743484929, 'log_operation_type', '日志操作类型', '1', NULL, '0', 0, 1, '2022-07-26 19:43:49', 1, '2022-07-26 19:43:49', '2022-07-26 19:43:48'); +INSERT INTO `sys_dict` VALUES (1551896925380038657, 'log_model_type', '日志模块类型', '1', NULL, '0', 5, 1, '2022-07-26 19:47:15', 1, '2022-07-27 10:21:11', '2022-07-27 10:21:11'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_dict_detail +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_detail`; +CREATE TABLE `sys_dict_detail` ( + `id` bigint(19) NOT NULL COMMENT '字典明细主键', + `type_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型ID', + `type_code` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型code 冗余字段', + `dict_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典名称', + `dict_value` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典值', + `iz_lock` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否内置 0否 1是', + `sort_no` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除状态', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` bigint(19) NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `dict_detail` (`type_code`,`dict_value`,`dict_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典表-明细'; + +-- ---------------------------- +-- Records of sys_dict_detail +-- ---------------------------- +BEGIN; +INSERT INTO `sys_dict_detail` VALUES (1308456445335597058, '1308396497528434689', '010110', 'abc', '0', '1', 0, '测试', '1', 1, 1, '2020-09-22 12:21:41', 1, '2020-09-22 12:22:11', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308637708302524418, '1308396497528434689', '010110', '销售部', '0', '1', 0, '测试', '1', 0, 1, '2020-09-23 00:21:58', 1, '2020-09-23 00:21:58', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308637974456291330, '1308396497528434689', '010110', '销售部', '0', '1', 0, '测试', '1', 0, 1, '2020-09-23 00:23:01', 1, '2020-09-23 00:23:01', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308638141389590529, '1308396497528434689', '010110', '销售部', '0', '1', 0, '测试', '1', 0, 1, '2020-09-23 00:23:41', 1, '2020-09-23 00:23:41', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308715719302586370, '1308396497528434689', '010110', '销售部', '0', '1', 0, '测试', '1', 0, 1, '2020-09-23 05:31:57', 1, '2020-09-23 05:31:57', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308716901383294978, '1308396497528434689', '010110', 'abc', '0', '1', 0, '测试', '1', 1, 1, '2020-09-23 05:36:39', 1, '2020-09-23 05:37:26', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308782561162293250, '1308782322607058946', 'test_type', '销售部', '0', '1', 0, '测试', '0', 2, 1, '2020-09-23 09:57:33', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308783750910078977, '1308782322607058946', 'test_type', '售后部', '1', '1', 0, '测试', '0', 16, 1, '2020-09-23 10:02:17', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308783873136291842, '1308782322607058946', 'test_type', '产品部', '2', '1', 0, '测试', '0', 16, 1, '2020-09-23 10:02:46', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308783908678823937, '1308782322607058946', 'test_type', '研发部', '3', '1', 0, '测试', '0', 16, 1, '2020-09-23 10:02:55', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308783942631714817, '1308782322607058946', 'test_type', '测试部', '4', '1', 0, '测试', '0', 16, 1, '2020-09-23 10:03:03', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308783992590069761, '1308782322607058946', 'test_type', '售前部', '5', '1', 0, '测试', '0', 16, 1, '2020-09-23 10:03:15', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1308784042569396225, '1308782322607058946', 'test_type', '设计部', '6', '1', 0, '测试', '0', 16, 1, '2020-09-23 10:03:26', 1, '2020-11-21 17:55:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314938241580838913, '1314920925140922369', 'test', '测试', '1', '0', 3, NULL, '0', 1, 1313694379541635074, '2020-10-10 22:38:02', 1313694379541635074, '2020-10-10 22:40:16', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314938442731270146, '1314920925140922369', 'test', '测试2', '2', '0', 2, NULL, '0', 2, 1313694379541635074, '2020-10-10 22:38:50', 1313694379541635074, '2020-10-11 10:21:30', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314939126788698114, '1314939057985335297', 'no_yes', '否', '0', '1', 1, NULL, '0', 0, 1313694379541635074, '2020-10-10 22:41:33', 1313694379541635074, '2020-10-10 22:41:33', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314939176172433409, '1314939057985335297', 'no_yes', '是', '1', '1', 2, NULL, '0', 0, 1313694379541635074, '2020-10-10 22:41:45', 1313694379541635074, '2020-10-10 22:41:45', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314939361581641730, '1314939286306467841', 'menu_type', '菜单', '1', '1', 1, NULL, '0', 3, 1313694379541635074, '2020-10-10 22:42:29', 1, '2020-10-11 09:56:11', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314939393605152770, '1314939286306467841', 'menu_type', '按钮', '2', '1', 2, NULL, '0', 2, 1313694379541635074, '2020-10-10 22:42:36', 1, '2020-10-11 09:56:11', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1314939432264052738, '1314939286306467841', 'menu_type', '外链', '3', '1', 3, NULL, '0', 2, 1313694379541635074, '2020-10-10 22:42:46', 1, '2020-10-11 09:56:11', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1327880400806977537, '1327879501833408513', 'table_type', '单表', '0', '1', 1, NULL, '0', 1, 1, '2020-11-15 15:45:33', 1, '2020-11-16 09:59:49', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1327880503319961602, '1327879501833408513', 'table_type', '树表', '1', '1', 2, NULL, '1', 1, 1, '2020-11-15 15:45:57', 1, '2020-11-16 09:59:49', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1327979358606700545, '1327979234979590146', 'jdbc_type', 'MySQL', 'mysql', '1', 1, NULL, '0', 2, 1, '2020-11-15 22:18:46', 1, '2020-11-16 09:59:45', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149020426481665, '1328148882811367425', 'mysql_data_type', 'tinyint', 'tinyint', '1', 1, NULL, '0', 3, 1, '2020-11-16 09:32:57', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149045797826561, '1328148882811367425', 'mysql_data_type', 'smallint', 'smallint', '1', 2, NULL, '0', 4, 1, '2020-11-16 09:33:03', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149070607134721, '1328148882811367425', 'mysql_data_type', 'mediumint', 'mediumint', '1', 3, NULL, '0', 3, 1, '2020-11-16 09:33:09', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149095005401090, '1328148882811367425', 'mysql_data_type', 'int', 'int', '1', 4, NULL, '0', 3, 1, '2020-11-16 09:33:15', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149122557784065, '1328148882811367425', 'mysql_data_type', 'bigint', 'bigint', '1', 5, NULL, '0', 3, 1, '2020-11-16 09:33:21', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149155734728706, '1328148882811367425', 'mysql_data_type', 'float', 'float', '1', 6, NULL, '0', 3, 1, '2020-11-16 09:33:29', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149182955761665, '1328148882811367425', 'mysql_data_type', 'double', 'double', '1', 7, NULL, '0', 3, 1, '2020-11-16 09:33:36', 1, '2020-11-16 09:59:55', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149212169089026, '1328148882811367425', 'mysql_data_type', 'char', 'char', '1', 9, NULL, '0', 4, 1, '2020-11-16 09:33:43', 1, '2020-11-18 17:36:44', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149233459376130, '1328148882811367425', 'mysql_data_type', 'varchar', 'varchar', '1', 10, NULL, '0', 4, 1, '2020-11-16 09:33:48', 1, '2020-11-18 17:36:52', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149257891196929, '1328148882811367425', 'mysql_data_type', 'tinytext', 'tinytext', '1', 11, NULL, '0', 4, 1, '2020-11-16 09:33:54', 1, '2020-11-18 17:36:58', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149280972451842, '1328148882811367425', 'mysql_data_type', 'text', 'text', '1', 12, NULL, '0', 4, 1, '2020-11-16 09:33:59', 1, '2020-11-18 17:37:09', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149313922904065, '1328148882811367425', 'mysql_data_type', 'mediumtext', 'mediumtext', '1', 13, NULL, '0', 4, 1, '2020-11-16 09:34:07', 1, '2020-11-18 17:37:12', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149342096044034, '1328148882811367425', 'mysql_data_type', 'longtext', 'longtext', '1', 14, NULL, '0', 4, 1, '2020-11-16 09:34:14', 1, '2020-11-18 17:37:16', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149374299910145, '1328148882811367425', 'mysql_data_type', 'date', 'date', '1', 15, NULL, '0', 4, 1, '2020-11-16 09:34:21', 1, '2020-11-18 17:37:19', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328149989512032258, '1328148882811367425', 'mysql_data_type', 'time', 'time', '1', 16, NULL, '0', 3, 1, '2020-11-16 09:36:48', 1, '2020-11-18 17:37:23', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328150026975555585, '1328148882811367425', 'mysql_data_type', 'datetime', 'datetime', '1', 17, NULL, '0', 3, 1, '2020-11-16 09:36:57', 1, '2020-11-18 17:37:25', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328150062320955393, '1328148882811367425', 'mysql_data_type', 'timestamp', 'timestamp', '1', 18, NULL, '0', 3, 1, '2020-11-16 09:37:05', 1, '2020-11-18 17:37:28', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328156042349883394, '1328155300805324801', 'show_type', '文本框', '0', '1', 1, NULL, '0', 1, 1, '2020-11-16 10:00:51', 1, '2020-11-16 10:00:56', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328156097270099970, '1328155300805324801', 'show_type', '文本域', '1', '1', 2, NULL, '0', 1, 1, '2020-11-16 10:01:04', 1, '2020-11-16 10:01:08', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328156163892424705, '1328155300805324801', 'show_type', '字典选择', '2', '1', 3, NULL, '0', 0, 1, '2020-11-16 10:01:20', 1, '2020-11-16 10:01:20', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328363850953424898, '1327979234979590146', 'jdbc_type', 'Oracle', 'oracle', '0', 2, NULL, '1', 0, 1, '2020-11-16 23:46:37', 1, '2020-11-16 23:46:37', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328591278510469121, '1328591039258980353', 'validate_type', '不能为空', 'IS_NOT_NULL', '1', 1, NULL, '0', 0, 1, '2020-11-17 14:50:19', 1, '2020-11-17 14:50:19', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1328591456541896705, '1328591039258980353', 'validate_type', '字母数字和下划线', 'IS_GENERAL', '1', 16, NULL, '0', 2, 1, '2020-11-17 14:51:02', 1, '2021-05-24 19:28:32', '2021-05-24 19:28:31'); +INSERT INTO `sys_dict_detail` VALUES (1328591535440949250, '1328591039258980353', 'validate_type', '数字', 'IS_NUMBER', '1', 3, NULL, '1', 0, 1, '2020-11-17 14:51:21', 1, '2020-11-17 14:51:21', '2021-05-24 19:27:11'); +INSERT INTO `sys_dict_detail` VALUES (1328591581578293249, '1328591039258980353', 'validate_type', '纯字母', 'IS_LETTER', '1', 5, NULL, '0', 1, 1, '2020-11-17 14:51:32', 1, '2021-05-24 19:26:07', '2021-05-24 19:26:07'); +INSERT INTO `sys_dict_detail` VALUES (1328591630144139266, '1328591039258980353', 'validate_type', '大写', 'IS_UPPER_CASE', '1', 6, NULL, '0', 1, 1, '2020-11-17 14:51:43', 1, '2021-05-24 19:26:11', '2021-05-24 19:26:10'); +INSERT INTO `sys_dict_detail` VALUES (1328591723169607682, '1328591039258980353', 'validate_type', '小写', 'IS_LOWER_CASE', '1', 7, NULL, '0', 1, 1, '2020-11-17 14:52:06', 1, '2021-05-24 19:26:17', '2021-05-24 19:26:16'); +INSERT INTO `sys_dict_detail` VALUES (1328591774579191810, '1328591039258980353', 'validate_type', 'Ipv4', 'IS_IPV4', '1', 9, NULL, '0', 2, 1, '2020-11-17 14:52:18', 1, '2021-05-24 19:26:37', '2021-05-24 19:26:36'); +INSERT INTO `sys_dict_detail` VALUES (1328591832049545218, '1328591039258980353', 'validate_type', '金额', 'IS_MONEY', '1', 11, NULL, '0', 1, 1, '2020-11-17 14:52:31', 1, '2021-05-24 19:27:32', '2021-05-24 19:27:31'); +INSERT INTO `sys_dict_detail` VALUES (1328591886462251009, '1328591039258980353', 'validate_type', '邮箱', 'IS_EMAIL', '1', 12, NULL, '0', 1, 1, '2020-11-17 14:52:44', 1, '2021-05-24 19:27:36', '2021-05-24 19:27:36'); +INSERT INTO `sys_dict_detail` VALUES (1328591938366763010, '1328591039258980353', 'validate_type', '手机号', 'IS_MOBILE', '1', 13, NULL, '0', 1, 1, '2020-11-17 14:52:57', 1, '2021-05-24 19:27:43', '2021-05-24 19:27:43'); +INSERT INTO `sys_dict_detail` VALUES (1328592000949972993, '1328591039258980353', 'validate_type', '18位身份证', 'IS_CITIZENID', '1', 14, NULL, '0', 1, 1, '2020-11-17 14:53:12', 1, '2021-05-24 19:28:07', '2021-05-24 19:28:06'); +INSERT INTO `sys_dict_detail` VALUES (1328592049868140546, '1328591039258980353', 'validate_type', '邮编', 'IS_ZIPCODE', '1', 18, NULL, '0', 1, 1, '2020-11-17 14:53:23', 1, '2021-05-24 19:29:09', '2021-05-24 19:29:09'); +INSERT INTO `sys_dict_detail` VALUES (1328592085637165058, '1328591039258980353', 'validate_type', 'URL', 'URL', '1', 19, NULL, '0', 1, 1, '2020-11-17 14:53:32', 1, '2021-05-24 19:29:14', '2021-05-24 19:29:14'); +INSERT INTO `sys_dict_detail` VALUES (1328592136035921921, '1328591039258980353', 'validate_type', '汉字', 'IS_CHINESE', '1', 15, NULL, '0', 1, 1, '2020-11-17 14:53:44', 1, '2021-05-24 19:28:19', '2021-05-24 19:28:18'); +INSERT INTO `sys_dict_detail` VALUES (1328592345788870658, '1328591039258980353', 'validate_type', '汉字或字母或数字或下划线', 'IS_GENERAL_WITH_CHINESE', '1', 17, NULL, '0', 1, 1, '2020-11-17 14:54:34', 1, '2021-05-24 19:28:39', '2021-05-24 19:28:39'); +INSERT INTO `sys_dict_detail` VALUES (1328592395894026242, '1328591039258980353', 'validate_type', 'MAC地址', 'IS_MAC', '1', 20, NULL, '0', 1, 1, '2020-11-17 14:54:46', 1, '2021-05-24 19:29:20', '2021-05-24 19:29:19'); +INSERT INTO `sys_dict_detail` VALUES (1328592440106184705, '1328591039258980353', 'validate_type', '中国车牌', 'IS_PLATE_NUMBER', '1', 21, NULL, '0', 1, 1, '2020-11-17 14:54:56', 1, '2021-05-24 19:29:26', '2021-05-24 19:29:26'); +INSERT INTO `sys_dict_detail` VALUES (1328995908293754881, '1328148882811367425', 'mysql_data_type', 'decimal', 'decimal', '1', 8, NULL, '0', 1, 1, '2020-11-18 17:38:11', 1, '2020-11-18 17:38:17', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006016235044865, '1329005625682427905', 'java_data_type', 'String', 'String', '1', 1, NULL, '0', 0, 1, '2020-11-18 18:18:21', 1, '2020-11-18 18:18:21', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006101010317313, '1329005625682427905', 'java_data_type', 'Byte', 'Byte', '1', 2, NULL, '0', 0, 1, '2020-11-18 18:18:41', 1, '2020-11-18 18:18:41', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006140738764802, '1329005625682427905', 'java_data_type', 'Short', 'Short', '1', 3, NULL, '0', 0, 1, '2020-11-18 18:18:50', 1, '2020-11-18 18:18:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006178210676738, '1329005625682427905', 'java_data_type', 'Integer', 'Integer', '1', 4, NULL, '0', 0, 1, '2020-11-18 18:18:59', 1, '2020-11-18 18:18:59', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006216005550081, '1329005625682427905', 'java_data_type', 'Long', 'Long', '1', 5, NULL, '0', 0, 1, '2020-11-18 18:19:08', 1, '2020-11-18 18:19:08', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006253049643010, '1329005625682427905', 'java_data_type', 'Float', 'Float', '1', 6, NULL, '0', 0, 1, '2020-11-18 18:19:17', 1, '2020-11-18 18:19:17', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006288294379521, '1329005625682427905', 'java_data_type', 'Double', 'Double', '1', 7, NULL, '0', 0, 1, '2020-11-18 18:19:26', 1, '2020-11-18 18:19:26', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006351808724993, '1329005625682427905', 'java_data_type', 'Character', 'Character', '1', 8, NULL, '0', 0, 1, '2020-11-18 18:19:41', 1, '2020-11-18 18:19:41', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329006390220161025, '1329005625682427905', 'java_data_type', 'Boolean', 'Boolean', '1', 9, NULL, '0', 0, 1, '2020-11-18 18:19:50', 1, '2020-11-18 18:19:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329012836630634497, '1329005625682427905', 'java_data_type', 'Date', 'Date', '1', 10, NULL, '0', 3, 1, '2020-11-18 18:45:27', 1, '2020-11-18 19:25:43', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1329025038242664450, '1328155300805324801', 'show_type', '时间控件', '3', '1', 4, NULL, '0', 1, 1, '2020-11-18 19:33:56', 1, '2020-11-27 14:21:24', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1330086999800979457, '1330086884696694786', 'query_type', '全值匹配', 'EQ', '1', 1, NULL, '0', 0, 1, '2020-11-21 17:53:47', 1, '2020-11-21 17:53:47', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1330087053454516225, '1330086884696694786', 'query_type', '模糊匹配', 'LIKE', '1', 2, NULL, '0', 0, 1, '2020-11-21 17:54:00', 1, '2020-11-21 17:54:00', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1330087452634816514, '1330086884696694786', 'query_type', '范围匹配', 'RANGE', '1', 3, NULL, '0', 0, 1, '2020-11-21 17:55:35', 1, '2020-11-21 17:55:35', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1332207946348371970, '1328155300805324801', 'show_type', '日期控件', '4', '1', 5, NULL, '0', 1, 1, '2020-11-27 14:21:40', 1, '2020-11-27 15:41:36', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1332662237399130113, '1332662182483107842', 'org_type', '公司', '1', '1', 1, NULL, '0', 0, 1, '2020-11-28 20:26:52', 1, '2020-11-28 20:26:52', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1332662266016866306, '1332662182483107842', 'org_type', '部门', '2', '1', 2, NULL, '0', 0, 1, '2020-11-28 20:26:59', 1, '2020-11-28 20:26:59', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1332662299038621697, '1332662182483107842', 'org_type', '岗位', '3', '1', 3, NULL, '0', 0, 1, '2020-11-28 20:27:06', 1, '2020-11-28 20:27:06', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346735934725267457, '1346735875094847489', '123123', '123', '123', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:30:43', 1313694379541635074, '2021-01-06 16:30:43', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346735949665378306, '1346735875094847489', '123123', '345', '345', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:30:46', 1313694379541635074, '2021-01-06 16:30:46', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346735962680303617, '1346735875094847489', '123123', '567', '567', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:30:49', 1313694379541635074, '2021-01-06 16:30:49', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346735975552622594, '1346735875094847489', '123123', '789', '789', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:30:52', 1313694379541635074, '2021-01-06 16:30:52', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346735992405336065, '1346735875094847489', '123123', '1244', '124314', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:30:56', 1313694379541635074, '2021-01-06 16:30:56', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346736008574377985, '1346735875094847489', '123123', '12332423', '12312312', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:31:00', 1313694379541635074, '2021-01-06 16:31:00', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1346736026190454785, '1346735875094847489', '123123', '123123', '12312333', '0', 1, NULL, '1', 0, 1313694379541635074, '2021-01-06 16:31:04', 1313694379541635074, '2021-01-06 16:31:04', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1358741824809709569, '1308782322607058946', 'test_type', '售后部1', '11', '0', 1, NULL, '1', 0, 1, '2021-02-08 19:37:50', 1, '2021-02-08 19:37:50', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1380172691483242497, '1380172509525946369', 'crypto_asymmetric', 'RSA', 'RSA', '1', 1, NULL, '0', 0, 1, '2021-04-08 22:56:27', 1, '2021-04-08 22:56:27', '2021-04-08 23:50:57'); +INSERT INTO `sys_dict_detail` VALUES (1388562258682822658, '1388562098925977601', 'storage_type', '本地', 'local', '1', 1, NULL, '0', 1, 1, '2021-05-02 02:33:35', 1, '2021-05-02 02:34:39', '2021-05-02 02:34:38'); +INSERT INTO `sys_dict_detail` VALUES (1389291796828073985, '1389291635615805442', 'password_level', '低', '0', '1', 1, NULL, '0', 0, 1, '2021-05-04 02:52:31', 1, '2021-05-04 02:52:31', '2021-05-04 02:52:30'); +INSERT INTO `sys_dict_detail` VALUES (1389291836380360706, '1389291635615805442', 'password_level', '中', '1', '1', 2, NULL, '0', 0, 1, '2021-05-04 02:52:40', 1, '2021-05-04 02:52:40', '2021-05-04 02:52:40'); +INSERT INTO `sys_dict_detail` VALUES (1389291876108808193, '1389291635615805442', 'password_level', '高', '2', '1', 3, NULL, '0', 0, 1, '2021-05-04 02:52:50', 1, '2021-05-04 02:52:50', '2021-05-04 02:52:49'); +INSERT INTO `sys_dict_detail` VALUES (1389291921797361666, '1389291635615805442', 'password_level', '很高', '3', '1', 4, NULL, '0', 0, 1, '2021-05-04 02:53:01', 1, '2021-05-04 02:53:01', '2021-05-04 02:53:00'); +INSERT INTO `sys_dict_detail` VALUES (1389291969885057026, '1389291635615805442', 'password_level', '非常高', '4', '1', 5, NULL, '0', 0, 1, '2021-05-04 02:53:12', 1, '2021-05-04 02:53:12', '2021-05-04 02:53:12'); +INSERT INTO `sys_dict_detail` VALUES (1396787751738630146, '1328591039258980353', 'validate_type', 'Ipv6', 'IS_IPV6', '1', 10, NULL, '0', 1, 1, '2021-05-24 19:18:46', 1, '2021-05-24 19:26:47', '2021-05-24 19:26:46'); +INSERT INTO `sys_dict_detail` VALUES (1396787839189868545, '1328591039258980353', 'validate_type', 'Ip', 'IS_IP', '1', 8, NULL, '0', 1, 1, '2021-05-24 19:19:07', 1, '2021-05-24 19:26:30', '2021-05-24 19:26:30'); +INSERT INTO `sys_dict_detail` VALUES (1396789224945967105, '1328591039258980353', 'validate_type', '整数', 'IS_INTEGER', '1', 2, NULL, '0', 1, 1, '2021-05-24 19:24:37', 1, '2021-05-24 19:25:43', '2021-05-24 19:25:43'); +INSERT INTO `sys_dict_detail` VALUES (1396789343724462082, '1328591039258980353', 'validate_type', '浮点数', 'IS_DECIMAL', '1', 3, NULL, '0', 1, 1, '2021-05-24 19:25:05', 1, '2021-05-24 19:25:50', '2021-05-24 19:25:49'); +INSERT INTO `sys_dict_detail` VALUES (1396789437249052674, '1328591039258980353', 'validate_type', '质数_素数', 'IS_PRIMES', '1', 4, NULL, '0', 1, 1, '2021-05-24 19:25:28', 1, '2021-05-24 19:25:54', '2021-05-24 19:25:54'); +INSERT INTO `sys_dict_detail` VALUES (1396790553273655298, '1328591039258980353', 'validate_type', '安全密码', 'IS_SECURITY_PASSWORD', '1', 22, NULL, '0', 0, 1, '2021-05-24 19:29:54', 1, '2021-05-24 19:29:54', '2021-05-24 19:29:53'); +INSERT INTO `sys_dict_detail` VALUES (1400399500568121346, '1388562098925977601', 'storage_type', '又拍云', 'upYun', '1', 2, NULL, '0', 0, 1, '2021-06-03 18:30:34', 1, '2021-06-03 18:30:34', '2021-06-03 18:30:33'); +INSERT INTO `sys_dict_detail` VALUES (1448557451719356417, '1448557351479685121', 'role_data_scope', '仅本人数据', '0', '1', 1, NULL, '0', 0, 1, '2021-10-14 15:53:04', 1, '2021-10-14 15:53:04', '2021-10-14 15:51:20'); +INSERT INTO `sys_dict_detail` VALUES (1448557556665036802, '1448557351479685121', 'role_data_scope', '本部门数据', '1', '1', 2, NULL, '0', 0, 1, '2021-10-14 15:53:29', 1, '2021-10-14 15:53:29', '2021-10-14 15:51:45'); +INSERT INTO `sys_dict_detail` VALUES (1448557649011027969, '1448557351479685121', 'role_data_scope', '本部门及以下数据', '2', '1', 3, NULL, '0', 0, 1, '2021-10-14 15:53:51', 1, '2021-10-14 15:53:51', '2021-10-14 15:52:07'); +INSERT INTO `sys_dict_detail` VALUES (1448557740778205185, '1448557351479685121', 'role_data_scope', '全部数据', '3', '1', 4, NULL, '0', 0, 1, '2021-10-14 15:54:13', 1, '2021-10-14 15:54:13', '2021-10-14 15:52:29'); +INSERT INTO `sys_dict_detail` VALUES (1463430673044529154, '1463430609630846978', 'menu_role_label', '系统模块', '0', '1', 1, NULL, '0', 0, 1, '2021-11-24 16:53:56', 1, '2021-11-24 16:53:56', '2021-11-24 16:51:57'); +INSERT INTO `sys_dict_detail` VALUES (1463430782889156609, '1463430609630846978', 'menu_role_label', '功能模块', '1', '1', 2, NULL, '0', 0, 1, '2021-11-24 16:54:23', 1, '2021-11-24 16:54:23', '2021-11-24 16:52:23'); +INSERT INTO `sys_dict_detail` VALUES (1551870261627457538, '1551869799540985858', 'login_from', 'PC', '0', '1', 1, NULL, '0', 0, 1, '2022-07-26 18:01:17', 1, '2022-07-26 18:01:17', '2022-07-26 18:01:17'); +INSERT INTO `sys_dict_detail` VALUES (1551870336856494081, '1551869799540985858', 'login_from', 'Android', '1', '1', 2, NULL, '0', 1, 1, '2022-07-26 18:01:35', 1, '2022-07-26 18:02:18', '2022-07-26 18:02:18'); +INSERT INTO `sys_dict_detail` VALUES (1551870413763252225, '1551869799540985858', 'login_from', 'IOS', '2', '1', 3, NULL, '0', 0, 1, '2022-07-26 18:01:54', 1, '2022-07-26 18:01:54', '2022-07-26 18:01:53'); +INSERT INTO `sys_dict_detail` VALUES (1551870759940132866, '1551869799540985858', 'login_from', 'H5', '3', '1', 4, NULL, '0', 0, 1, '2022-07-26 18:03:16', 1, '2022-07-26 18:03:16', '2022-07-26 18:03:16'); +INSERT INTO `sys_dict_detail` VALUES (1551870831604011009, '1551869799540985858', 'login_from', '未知', '-1', '1', 99, NULL, '0', 0, 1, '2022-07-26 18:03:33', 1, '2022-07-26 18:03:33', '2022-07-26 18:03:33'); +INSERT INTO `sys_dict_detail` VALUES (1551895152049278977, '1551894955382558721', 'log_type', 'WEB', '0', '1', 1, NULL, '0', 0, 1, '2022-07-26 19:40:12', 1, '2022-07-26 19:40:12', '2022-07-26 19:40:11'); +INSERT INTO `sys_dict_detail` VALUES (1551895211306405889, '1551894955382558721', 'log_type', '客户端', '1', '1', 2, NULL, '0', 0, 1, '2022-07-26 19:40:26', 1, '2022-07-26 19:40:26', '2022-07-26 19:40:25'); +INSERT INTO `sys_dict_detail` VALUES (1551895274808168449, '1551894955382558721', 'log_type', '后台', '2', '1', 3, NULL, '0', 0, 1, '2022-07-26 19:40:41', 1, '2022-07-26 19:40:41', '2022-07-26 19:40:40'); +INSERT INTO `sys_dict_detail` VALUES (1551895331154448386, '1551894955382558721', 'log_type', '程序自动', '3', '1', 4, NULL, '0', 0, 1, '2022-07-26 19:40:54', 1, '2022-07-26 19:40:54', '2022-07-26 19:40:54'); +INSERT INTO `sys_dict_detail` VALUES (1551895490605109250, '1551895408610660353', 'log_level', 'DEBUG', '-1', '1', 1, NULL, '0', 1, 1, '2022-07-26 19:41:32', 1, '2022-07-27 11:18:18', '2022-07-27 11:18:17'); +INSERT INTO `sys_dict_detail` VALUES (1551895541041614850, '1551895408610660353', 'log_level', 'INFO', '0', '1', 2, NULL, '0', 1, 1, '2022-07-26 19:41:44', 1, '2022-07-27 11:18:18', '2022-07-27 11:18:17'); +INSERT INTO `sys_dict_detail` VALUES (1551895601477341185, '1551895408610660353', 'log_level', 'WARN', '1', '1', 3, NULL, '0', 1, 1, '2022-07-26 19:41:59', 1, '2022-07-27 11:18:18', '2022-07-27 11:18:17'); +INSERT INTO `sys_dict_detail` VALUES (1551895666078011394, '1551895408610660353', 'log_level', 'ERROR', '2', '1', 4, NULL, '0', 1, 1, '2022-07-26 19:42:14', 1, '2022-07-27 11:18:18', '2022-07-27 11:18:18'); +INSERT INTO `sys_dict_detail` VALUES (1551895739352502274, '1551895408610660353', 'log_level', 'TRACE', '3', '1', 5, NULL, '0', 1, 1, '2022-07-26 19:42:32', 1, '2022-07-27 11:18:18', '2022-07-27 11:18:18'); +INSERT INTO `sys_dict_detail` VALUES (1551896512073322498, '1551896061743484929', 'log_operation_type', '未知', 'unknown', '1', 1, NULL, '0', 0, 1, '2022-07-26 19:45:36', 1, '2022-07-26 19:45:36', '2022-07-26 19:45:35'); +INSERT INTO `sys_dict_detail` VALUES (1551896567580741633, '1551896061743484929', 'log_operation_type', '删除', 'delete', '1', 2, NULL, '0', 0, 1, '2022-07-26 19:45:49', 1, '2022-07-26 19:45:49', '2022-07-26 19:45:49'); +INSERT INTO `sys_dict_detail` VALUES (1551896632240132097, '1551896061743484929', 'log_operation_type', '查询', 'select', '1', 3, NULL, '0', 0, 1, '2022-07-26 19:46:05', 1, '2022-07-26 19:46:05', '2022-07-26 19:46:04'); +INSERT INTO `sys_dict_detail` VALUES (1551896695058223106, '1551896061743484929', 'log_operation_type', '更新', 'update', '1', 4, NULL, '0', 0, 1, '2022-07-26 19:46:20', 1, '2022-07-26 19:46:20', '2022-07-26 19:46:19'); +INSERT INTO `sys_dict_detail` VALUES (1551896736737021953, '1551896061743484929', 'log_operation_type', '新增', 'insert', '1', 5, NULL, '0', 0, 1, '2022-07-26 19:46:30', 1, '2022-07-26 19:46:30', '2022-07-26 19:46:29'); +INSERT INTO `sys_dict_detail` VALUES (1551898038988824578, '1551896925380038657', 'log_model_type', '公共模块', '00', '1', 1, NULL, '0', 5, 1, '2022-07-26 19:51:40', 1, '2022-07-27 10:21:20', '2022-07-27 10:21:20'); +INSERT INTO `sys_dict_detail` VALUES (1551898084056621058, '1551896925380038657', 'log_model_type', '用户模块', '01', '1', 2, NULL, '0', 5, 1, '2022-07-26 19:51:51', 1, '2022-07-27 10:21:24', '2022-07-27 10:21:23'); +INSERT INTO `sys_dict_detail` VALUES (1551898133155143682, '1551896925380038657', 'log_model_type', '角色模块', '02', '1', 3, NULL, '0', 5, 1, '2022-07-26 19:52:02', 1, '2022-07-27 10:21:26', '2022-07-27 10:21:26'); +INSERT INTO `sys_dict_detail` VALUES (1551898192265469953, '1551896925380038657', 'log_model_type', '菜单模块', '03', '1', 4, NULL, '0', 5, 1, '2022-07-26 19:52:17', 1, '2022-07-27 10:21:28', '2022-07-27 10:21:28'); +INSERT INTO `sys_dict_detail` VALUES (1551898257474314242, '1551896925380038657', 'log_model_type', '组织模块', '04', '1', 5, NULL, '0', 5, 1, '2022-07-26 19:52:32', 1, '2022-07-27 10:21:30', '2022-07-27 10:21:30'); +INSERT INTO `sys_dict_detail` VALUES (1551898350382342146, '1551896925380038657', 'log_model_type', '字典模块', '05', '1', 6, NULL, '0', 5, 1, '2022-07-26 19:52:54', 1, '2022-07-27 10:21:32', '2022-07-27 10:21:32'); +INSERT INTO `sys_dict_detail` VALUES (1551898407601037313, '1551896925380038657', 'log_model_type', '租户模块', '06', '1', 7, NULL, '0', 5, 1, '2022-07-26 19:53:08', 1, '2022-07-27 10:21:32', '2022-07-27 10:21:32'); +INSERT INTO `sys_dict_detail` VALUES (1551898482796519426, '1551896925380038657', 'log_model_type', '地区模块', '07', '1', 8, NULL, '0', 5, 1, '2022-07-26 19:53:26', 1, '2022-07-27 10:21:32', '2022-07-27 10:21:32'); +INSERT INTO `sys_dict_detail` VALUES (1551898551625048066, '1551896925380038657', 'log_model_type', '监控模块', '08', '1', 9, NULL, '0', 5, 1, '2022-07-26 19:53:42', 1, '2022-07-27 10:21:32', '2022-07-27 10:21:32'); +INSERT INTO `sys_dict_detail` VALUES (1551898616208941057, '1551896925380038657', 'log_model_type', '代码生成器', '09', '1', 10, NULL, '0', 5, 1, '2022-07-26 19:53:58', 1, '2022-07-27 10:21:33', '2022-07-27 10:21:32'); +INSERT INTO `sys_dict_detail` VALUES (1551898680184659970, '1551896925380038657', 'log_model_type', '测试模块', '100', '0', 11, NULL, '0', 5, 1, '2022-07-26 19:54:13', 1, '2022-07-27 10:21:33', '2022-07-27 10:21:32'); +INSERT INTO `sys_dict_detail` VALUES (1551898752452517889, '1551896925380038657', 'log_model_type', '测试用户模块', '101', '0', 12, NULL, '0', 5, 1, '2022-07-26 19:54:30', 1, '2022-07-27 10:21:33', '2022-07-27 10:21:33'); +INSERT INTO `sys_dict_detail` VALUES (1551898808907849730, '1551896925380038657', 'log_model_type', '测试汽车模块', '102', '0', 13, NULL, '0', 5, 1, '2022-07-26 19:54:44', 1, '2022-07-27 10:21:33', '2022-07-27 10:21:33'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_login_logs +-- ---------------------------- +DROP TABLE IF EXISTS `sys_login_logs`; +CREATE TABLE `sys_login_logs` ( + `id` bigint(19) NOT NULL COMMENT '唯一主键', + `org_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '父级主键集合', + `type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '日志类型 1登录日志 2退出日志', + `remote_addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作IP地址', + `user_agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户代理', + `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录账户', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '真实姓名', + `login_from` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登陆来源', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `version` int(11) NOT NULL COMMENT '版本', + `create_by` bigint(19) NOT NULL COMMENT '创建者', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` bigint(19) NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_username` (`username`) USING BTREE, + KEY `idx_loginfrom` (`login_from`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='登录信息表'; + +-- ---------------------------- +-- Table structure for sys_logs +-- ---------------------------- +DROP TABLE IF EXISTS `sys_logs`; +CREATE TABLE `sys_logs` ( + `id` bigint(19) NOT NULL COMMENT '唯一主键', + `type` varchar(1) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '1' COMMENT '日志类型', + `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '日志标题', + `remote_addr` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '操作IP地址', + `user_agent` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '用户代理', + `request_uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '请求URI', + `method` varchar(5) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '操作方式', + `timeout` bigint(20) DEFAULT NULL COMMENT '执行时间', + `params` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT '操作提交的数据', + `exception` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT '异常信息', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建者', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` bigint(19) NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + `org_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '父级主键集合', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + PRIMARY KEY (`id`) USING BTREE, + KEY `sys_log_create_by` (`create_by`) USING BTREE, + KEY `sys_log_request_uri` (`request_uri`) USING BTREE, + KEY `sys_log_type` (`type`) USING BTREE, + KEY `sys_log_create_date` (`create_time`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='日志表'; + +-- ---------------------------- +-- Table structure for sys_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `id` bigint(19) NOT NULL COMMENT '功能主键', + `parent_id` bigint(19) NOT NULL DEFAULT '0' COMMENT '父级主键', + `parent_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '父级主键集合', + `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称', + `permissions` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '权限', + `icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '图标', + `label` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '菜单标签 0-系统菜单 1-功能菜单', + `type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型: 1-菜单 2-按钮 3-链接', + `url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'url地址', + `component` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '组件', + `redirect` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '重定向', + `sort_no` int(11) NOT NULL COMMENT '排序', + `always_show` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否总是显示 0是 1否', + `hidden` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否隐藏 0是 1否', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除状态', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `pid` (`parent_id`) USING BTREE COMMENT '上级id' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统功能表'; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +BEGIN; +INSERT INTO `sys_menu` VALUES (1, 0, '0,1', '系统配置', NULL, 'cog', '0', '1', '/system', 'Layout', NULL, 3, '0', '0', '0', 2, 1, '2020-04-14 19:07:31', 1, '2021-05-04 20:34:03', '2022-04-29 17:22:11'); +INSERT INTO `sys_menu` VALUES (2, 1, '0,1,2', '菜单管理', NULL, NULL, '0', '1', 'menu', 'views/modules/system/menuManagement/index', NULL, 1, '0', '0', '0', 0, 1, '2020-04-14 19:07:31', 1, '2020-10-07 23:49:36', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (3, 1460639200696160257, '0,1460639200696160257,3', '用户管理', NULL, '', '0,1', '1', 'user', 'views/modules/system/userManagement/index', NULL, 2, '0', '0', '0', 1, 1, '2020-04-14 19:07:31', 1, '2021-11-17 00:02:41', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (4, 1460639200696160257, '0,1460639200696160257,4', '角色管理', NULL, NULL, '0,1', '1', 'role', 'views/modules/system/roleManagement/index', NULL, 3, '0', '0', '0', 1, 1, '2020-09-24 14:01:31', 1, '2021-11-17 00:02:49', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1312756531833356289, 1, '0,1,1312756531833356289', '字典管理', NULL, NULL, '0', '1', 'dict', 'views/modules/system/dictManagement/index', NULL, 6, '0', '0', '0', 2, 1, '2020-10-04 09:08:42', 1, '2021-04-29 13:02:37', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1313789204920131585, 3, '0,1460639200696160257,3,1313789204920131585', '增加', 'system_user_insert', NULL, '0,1', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-10-07 05:32:10', 1, '2020-10-07 10:42:13', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313789308506857474, 3, '0,1460639200696160257,3,1313789308506857474', '修改', 'system_user_update', NULL, '0,1', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2020-10-07 05:32:35', 1, '2020-10-07 06:42:26', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313789400169177089, 3, '0,1460639200696160257,3,1313789400169177089', '删除', 'system_user_delete', NULL, '0,1', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2020-10-07 05:32:57', 1, '2020-10-07 06:42:38', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313789529840279554, 3, '0,1460639200696160257,3,1313789529840279554', '导出', 'system_user_export', NULL, '0,1', '2', NULL, NULL, NULL, 5, '0', '0', '0', 0, 1, '2020-10-07 05:33:28', 1, '2020-10-07 06:42:43', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313806847370620930, 3, '0,1460639200696160257,3,1313806847370620930', '查看', 'system_user_select', NULL, '0,1', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-10-07 06:42:16', 1, '2020-10-07 06:42:16', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313864645827678210, 3, '0,1460639200696160257,3,1313864645827678210', '授权角色', 'system_user_setRole', '', '0,1', '2', NULL, NULL, NULL, 6, '0', '0', '0', 1, 1, '2020-10-07 10:31:57', 1, '2021-11-30 15:44:40', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313864777918894082, 3, '0,1460639200696160257,3,1313864777918894082', '修改密码', 'system_user_updatePassword', NULL, '0,1', '2', NULL, NULL, NULL, 7, '0', '0', '0', 0, 1, '2020-10-07 10:32:28', 1, '2020-10-07 10:32:28', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313866576193212418, 2, '0,1,2,1313866576193212418', '增加', 'system_menu_insert', NULL, '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-10-07 10:39:37', 1, '2020-10-07 10:42:03', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313866652533739522, 2, '0,1,2,1313866652533739522', '修改', 'system_menu_update', NULL, '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2020-10-07 10:39:55', 1, '2020-10-07 10:41:01', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313866789838475265, 2, '0,1,2,1313866789838475265', '删除', 'system_menu_delete', NULL, '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2020-10-07 10:40:28', 1, '2020-10-07 10:41:11', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313866828526735361, 2, '0,1,2,1313866828526735361', '查看', 'system_menu_select', NULL, '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 2, 1, '2020-10-07 10:40:37', 1, '2021-04-09 23:51:37', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867061172195330, 4, '0,1460639200696160257,4,1313867061172195330', '查看', 'system_role_select', NULL, '0,1', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-10-07 10:41:33', 1, '2020-10-07 10:41:33', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867122731995137, 4, '0,1460639200696160257,4,1313867122731995137', '增加', 'system_role_insert', NULL, '0,1', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-10-07 10:41:47', 1, '2020-10-07 10:42:25', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867360502894594, 4, '0,1460639200696160257,4,1313867360502894594', '修改', 'system_role_update', NULL, '0,1', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2020-10-07 10:42:44', 1, '2020-10-07 10:42:44', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867409949544450, 4, '0,1460639200696160257,4,1313867409949544450', '删除', 'system_role_delete', NULL, '0,1', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2020-10-07 10:42:56', 1, '2020-10-07 10:42:56', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867556498526209, 1312756531833356289, '0,1,1312756531833356289,1313867556498526209', '查看', 'system_dict_select', NULL, '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-10-07 10:43:31', 1, '2020-10-07 10:43:31', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867617949274113, 1312756531833356289, '0,1,1312756531833356289,1313867617949274113', '增加', 'system_dict_insert', NULL, '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-10-07 10:43:45', 1, '2020-10-07 10:43:51', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867682814185474, 1312756531833356289, '0,1,1312756531833356289,1313867682814185474', '修改', 'system_dict_update', NULL, '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2020-10-07 10:44:01', 1, '2020-10-07 10:44:01', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313867732508299265, 1312756531833356289, '0,1,1312756531833356289,1313867732508299265', '删除', 'system_dict_delete', NULL, '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2020-10-07 10:44:13', 1, '2020-10-07 10:44:13', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1313885644824522754, 4, '0,1460639200696160257,4,1313885644824522754', '设置菜单权限', 'system_role_setMenuPerms', NULL, '0,1', '2', NULL, NULL, NULL, 5, '0', '0', '0', 2, 1, '2020-10-07 11:55:23', 1, '2021-10-14 14:31:37', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314066547072872450, 0, '0,1314066547072872450', '首页', NULL, 'home', '0,1', '1', '/', 'Layout', 'index', 1, '0', '0', '0', 13, 1, '2020-10-07 23:54:14', 1, '2021-11-25 13:46:11', '2022-04-29 17:22:11'); +INSERT INTO `sys_menu` VALUES (1314066863436640258, 1314066547072872450, '0,1314066547072872450,1314066863436640258', '首页', NULL, 'home', '0,1', '1', 'index', 'views/index/index', NULL, 1, '0', '0', '0', 1, 1, '2020-10-07 23:55:29', 1, '2021-11-24 16:58:05', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1314068325453574145, 0, '0,1314068325453574145', '开发工具', NULL, 'tools', '0', '1', '/deve', 'Layout', NULL, 100, '0', '0', '0', 1, 1, '2020-10-08 00:01:18', 1, '2021-11-26 18:56:20', '2022-04-29 17:22:11'); +INSERT INTO `sys_menu` VALUES (1314071137365307394, 1314068325453574145, '0,1314068325453574145,1314071137365307394', '组件', NULL, '', '0', '1', 'vab', 'EmptyLayout', NULL, 3, '0', '0', '0', 1, 1, '2020-10-08 00:12:28', 1, '2020-11-15 16:36:56', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1314074765178187777, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314074765178187777', '外链', NULL, NULL, '0', '3', 'https://github.com/hiparker/opsli-boot?utm_source=gold_browser_extension', NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-10-08 00:26:53', 1, '2020-10-08 00:30:21', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314075128635600897, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314075128635600897', '图标', NULL, NULL, '0', '1', 'icon', 'EmptyLayout', NULL, 2, '0', '0', '0', 0, 1, '2020-10-08 00:28:20', 1, '2020-10-08 00:48:16', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314075267769053186, 1314075128635600897, '0,1314068325453574145,1314071137365307394,1314075128635600897,1314075267769053186', '常规图标', NULL, NULL, '0', '1', 'awesomeIcon', 'views/vab/icon/index', NULL, 1, '0', '0', '0', 0, 1, '2020-10-08 00:28:53', 1, '2020-10-08 00:48:19', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1314075542684708865, 1314075128635600897, '0,1314068325453574145,1314071137365307394,1314075128635600897,1314075542684708865', '小清新图标', NULL, NULL, '0', '1', 'remixIcon', 'views/vab/icon/remixIcon', NULL, 2, '0', '0', '0', 0, 1, '2020-10-08 00:29:58', 1, '2020-10-08 00:48:22', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1314075764852797442, 1314075128635600897, '0,1314068325453574145,1314071137365307394,1314075128635600897,1314075764852797442', '多彩图标', NULL, NULL, '0', '1', 'colorfulIcon', 'views/vab/icon/colorfulIcon', NULL, 3, '0', '0', '0', 0, 1, '2020-10-08 00:30:51', 1, '2020-10-08 00:48:25', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1314075970382082050, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314075970382082050', '表格', NULL, NULL, '0', '1', 'table', 'EmptyLayout', NULL, 3, '0', '0', '0', 0, 1, '2020-10-08 00:31:40', 1, '2020-10-08 00:48:31', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314076169481498625, 1314075970382082050, '0,1314068325453574145,1314071137365307394,1314075970382082050,1314076169481498625', '综合表格', NULL, NULL, '0', '1', 'comprehensiveTable', 'views/vab/table/index', NULL, 1, '0', '0', '0', 0, 1, '2020-10-08 00:32:28', 1, '2020-10-08 00:48:34', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1314076280542474242, 1314075970382082050, '0,1314068325453574145,1314071137365307394,1314075970382082050,1314076280542474242', '行内编辑', NULL, NULL, '0', '1', 'inlineEditTable', 'views/vab/table/inlineEditTable', NULL, 2, '0', '0', '0', 0, 1, '2020-10-08 00:32:54', 1, '2020-10-08 00:32:54', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1314076678317682689, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314076678317682689', '地图', NULL, NULL, '0', '1', 'map', 'views/vab/map/index', NULL, 4, '0', '0', '0', 0, 1, '2020-10-08 00:34:29', 1, '2020-10-08 00:34:29', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077008057085954, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077008057085954', 'WebSocket', NULL, NULL, '0', '1', 'websocket', 'views/vab/webSocket/index', NULL, 5, '0', '0', '0', 0, 1, '2020-10-08 00:35:48', 1, '2020-10-08 00:35:48', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077108560998402, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077108560998402', '表单', NULL, NULL, '0', '1', 'form', 'views/vab/form/index', NULL, 6, '0', '0', '0', 0, 1, '2020-10-08 00:36:12', 1, '2020-10-08 00:36:12', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077229235318786, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077229235318786', '常用组件', NULL, NULL, '0', '1', 'element', 'views/vab/element/index', NULL, 7, '0', '0', '0', 0, 1, '2020-10-08 00:36:40', 1, '2020-10-08 00:36:52', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077399507283970, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077399507283970', '树', NULL, NULL, '0', '1', 'tree', 'views/vab/tree/index', NULL, 8, '0', '0', '0', 0, 1, '2020-10-08 00:37:21', 1, '2020-10-08 00:37:21', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077518340304897, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077518340304897', '卡片', NULL, NULL, '0', '1', 'card', 'views/vab/card/index', NULL, 9, '0', '0', '0', 0, 1, '2020-10-08 00:37:49', 1, '2020-10-08 00:37:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077631905280001, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077631905280001', '滚动侦测', NULL, NULL, '0', '1', 'betterscroll', 'views/vab/betterScroll/index', NULL, 10, '0', '0', '0', 0, 1, '2020-10-08 00:38:16', 1, '2020-10-08 00:38:16', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314077729003417602, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314077729003417602', '验证码', NULL, NULL, '0', '1', 'verify', 'views/vab/verify/index', NULL, 11, '0', '0', '0', 0, 1, '2020-10-08 00:38:40', 1, '2020-10-08 00:38:40', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314120834868060162, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314120834868060162', '放大镜', NULL, NULL, '0', '1', 'magnifier', 'views/vab/magnifier/index', NULL, 12, '0', '0', '0', 0, 1, '2020-10-08 03:29:57', 1, '2020-10-08 03:30:45', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314121004749955073, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314121004749955073', '图表', NULL, NULL, '0', '1', 'echarts', 'views/vab/echarts/index', NULL, 13, '0', '0', '0', 0, 1, '2020-10-08 03:30:37', 1, '2020-10-08 03:30:54', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314121200103858178, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314121200103858178', 'Loading', NULL, NULL, '0', '1', 'loading', 'views/vab/loading/index', NULL, 14, '0', '0', '0', 0, 1, '2020-10-08 03:31:24', 1, '2020-10-08 03:31:24', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314121675192672257, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314121675192672257', '视频播放器', NULL, NULL, '0', '1', 'player', 'views/vab/player/index', NULL, 15, '0', '0', '0', 0, 1, '2020-10-08 03:33:17', 1, '2020-10-08 03:33:17', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314121808793837570, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314121808793837570', 'Markdown编辑器', NULL, NULL, '0', '1', 'markdownEditor', 'views/vab/markdownEditor/index', NULL, 16, '0', '0', '0', 0, 1, '2020-10-08 03:33:49', 1, '2020-10-08 03:33:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314121928784486402, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314121928784486402', '富文本编辑器', NULL, NULL, '0', '1', 'editor', 'views/vab/editor/index', NULL, 17, '0', '0', '0', 0, 1, '2020-10-08 03:34:18', 1, '2020-10-08 03:35:21', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122020136427521, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122020136427521', '二维码', NULL, NULL, '0', '1', 'qrCode', 'views/vab/qrCode/index', NULL, 18, '0', '0', '0', 0, 1, '2020-10-08 03:34:39', 1, '2020-10-08 03:35:26', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122123047870466, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122123047870466', '返回顶部', NULL, NULL, '0', '1', 'backToTop', 'views/vab/backToTop/index', NULL, 20, '0', '0', '0', 0, 1, '2020-10-08 03:35:04', 1, '2020-10-08 03:37:41', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122353273217025, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122353273217025', '图像拖拽比对', NULL, NULL, '0', '1', 'imgComparison', 'views/vab/imgComparison/index', NULL, 19, '0', '0', '0', 0, 1, '2020-10-08 03:35:59', 1, '2020-10-08 03:35:59', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122457908518914, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122457908518914', '代码生成机', NULL, NULL, '0', '1', 'codeGenerator', 'views/vab/codeGenerator/index', NULL, 21, '0', '0', '0', 1, 1, '2020-10-08 03:36:24', 1313694379541635074, '2020-10-11 17:21:34', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122556776652802, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122556776652802', 'markdown阅读器', NULL, NULL, '0', '1', 'markdown', 'views/vab/markdown/index', NULL, 22, '0', '0', '0', 0, 1, '2020-10-08 03:36:47', 1, '2020-10-08 03:37:58', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122628184678401, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122628184678401', '小组件', NULL, NULL, '0', '1', 'smallComponents', 'views/vab/smallComponents/index', NULL, 23, '0', '0', '0', 0, 1, '2020-10-08 03:37:04', 1, '2020-10-08 03:38:03', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314122717041008641, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314122717041008641', '上传', NULL, NULL, '0', '1', 'upload', 'views/vab/upload/index', NULL, 24, '0', '0', '0', 0, 1, '2020-10-08 03:37:26', 1, '2020-10-08 03:38:10', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314123071354839041, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314123071354839041', 'Sticky吸附', NULL, NULL, '0', '1', 'sticky', 'views/vab/sticky/index', NULL, 25, '0', '0', '0', 0, 1, '2020-10-08 03:38:50', 1, '2020-10-08 03:38:59', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314123272790482945, 1314071137365307394, '0,1314068325453574145,1314071137365307394,1314123272790482945', '错误日志模拟', NULL, NULL, '0', '1', 'errorLog', 'views/vab/errorLog/index', NULL, 26, '0', '0', '0', 0, 1, '2020-10-08 03:39:38', 1, '2020-10-08 03:39:38', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314123690283114498, 1314068325453574145, '0,1314068325453574145,1314123690283114498', '商城', NULL, NULL, '0', '1', 'mall', 'EmptyLayout', NULL, 4, '0', '0', '0', 1, 1, '2020-10-08 03:41:18', 1, '2020-11-15 16:37:13', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1314123894637993985, 1314123690283114498, '0,1314068325453574145,1314123690283114498,1314123894637993985', '支付', NULL, NULL, '0', '1', 'pay', 'views/mall/pay/index', NULL, 1, '0', '0', '0', 0, 1, '2020-10-08 03:42:06', 1, '2020-10-08 03:42:06', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314123990633029633, 1314123690283114498, '0,1314068325453574145,1314123690283114498,1314123990633029633', '商品列表', NULL, NULL, '0', '1', 'goodsList', 'views/mall/goodsList/index', NULL, 2, '0', '0', '0', 0, 1, '2020-10-08 03:42:29', 1, '2020-10-08 03:43:01', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314124102365093890, 1314123690283114498, '0,1314068325453574145,1314123690283114498,1314124102365093890', '商品详情', NULL, NULL, '0', '1', 'goodsDetail', 'views/mall/goodsDetail/index', NULL, 3, '0', '0', '0', 0, 1, '2020-10-08 03:42:56', 1, '2020-10-08 03:42:56', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1314610817013919745, 0, '0,1314610817013919745', '运维工具', NULL, 'laptop-code', '0', '1', '/devops', 'Layout', 'noRedirect', 99, '0', '0', '0', 1, 1, '2020-10-09 11:56:58', 1, '2020-11-13 11:05:54', '2022-04-29 17:22:11'); +INSERT INTO `sys_menu` VALUES (1314616518671085570, 1504776412970254338, '0,1504776412970254338,1314616518671085570', '行为日志', NULL, NULL, '0,1', '1', 'logs', 'views/modules/system/operationLogsManagement/index', NULL, 2, '0', '0', '0', 3, 1, '2020-10-09 12:19:37', 1, '2022-07-26 19:33:51', '2022-07-26 19:33:51'); +INSERT INTO `sys_menu` VALUES (1314782679522099201, 1314616518671085570, '0,1504776412970254338,1314616518671085570,1314782679522099201', '查看', 'system_op_logs_select', NULL, '0,1', '2', NULL, NULL, NULL, 1, '0', '0', '0', 2, 1, '2020-10-09 23:19:53', 1, '2022-07-26 20:09:12', '2022-07-26 20:09:11'); +INSERT INTO `sys_menu` VALUES (1314786106243301378, 1314068325453574145, '0,1314068325453574145,1314786106243301378', '系统接口', NULL, NULL, '0', '3', 'http://${BASE_PATH}/doc.html', NULL, NULL, 2, '0', '0', '0', 1, 1, '2020-10-09 23:33:30', 1, '2020-11-15 16:37:23', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1314799744349913090, 1314610817013919745, '0,1314610817013919745,1314799744349913090', '数据库监控', NULL, NULL, '0', '3', 'http://${BASE_PATH}/druid', NULL, NULL, 3, '0', '0', '0', 1, 1, '2020-10-10 00:27:42', 1313694379541635074, '2021-01-18 11:45:37', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1314884045724717057, 1312756531833356289, '0,1,1312756531833356289,1314884045724717057', '设置字典', 'system_dict_setDict', NULL, '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-10-10 19:02:41', 1, '2020-10-10 19:02:41', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1315201380721446914, 1460639200696160257, '0,1460639200696160257,1315201380721446914', '租户管理', NULL, NULL, '0', '1', 'tenant', 'views/modules/system/tenantManagement/index', NULL, 5, '0', '0', '0', 5, 1, '2020-10-11 16:03:39', 1, '2021-11-29 17:57:53', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1315201734892670977, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1315201734892670977', '查看', 'system_tenant_select', NULL, '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-10-11 16:05:04', 1, '2020-10-11 16:05:04', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1315201809668722690, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1315201809668722690', '增加', 'system_tenant_insert', NULL, '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-10-11 16:05:21', 1, '2020-10-11 16:05:21', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1315201864219840513, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1315201864219840513', '修改', 'system_tenant_update', NULL, '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2020-10-11 16:05:34', 1, '2020-10-11 16:05:34', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1315201925477650433, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1315201925477650433', '删除', 'system_tenant_delete', NULL, '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 1, 1, '2020-10-11 16:05:49', 1, '2020-10-11 16:12:27', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1327085543511293954, 0, '0,1327085543511293954', '测试模块', NULL, 'box', '0', '1', '/gentest', 'Layout', NULL, 4, '0', '0', '0', 78, 1, '2020-11-13 11:07:04', 1, '2022-04-29 16:36:49', '2022-04-29 16:36:49'); +INSERT INTO `sys_menu` VALUES (1327085856930660353, 1327085543511293954, '0,1327085543511293954,1327085856930660353', '业务测试', NULL, '', '0', '1', 'test', 'views/modules/test/index', '', 1, '0', '0', '0', 12, 1, '2020-11-13 11:08:19', 1, '2022-04-29 16:36:49', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1327086205548625921, 1327085856930660353, '0,1327085543511293954,1327085856930660353,1327086205548625921', '查看', 'gentest_test_select', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 8, 1, '2020-11-13 11:09:42', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1327086298750255105, 1327085856930660353, '0,1327085543511293954,1327085856930660353,1327086298750255105', '增加', 'gentest_test_insert', '', '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 8, 1, '2020-11-13 11:10:04', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1327086378794352642, 1327085856930660353, '0,1327085543511293954,1327085856930660353,1327086378794352642', '修改', 'gentest_test_update', '', '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 6, 1, '2020-11-13 11:10:23', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1327086433609711617, 1327085856930660353, '0,1327085543511293954,1327085856930660353,1327086433609711617', '删除', 'gentest_test_delete', '', '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 7, 1, '2020-11-13 11:10:37', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1327893773049262082, 1397807288445526017, '0,1314068325453574145,1397807288445526017,1327893773049262082', '代码生成器', NULL, '', '0', '1', 'creater', 'views/modules/generator/table/index', NULL, 1, '0', '0', '0', 3, 1, '2020-11-15 16:38:41', 1, '2021-05-27 14:50:14', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1327894701135491073, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1327894701135491073', '查看', 'dev_generator_select', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 2, 1, '2020-11-15 16:42:22', 1, '2020-11-15 16:43:08', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1327894767283859457, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1327894767283859457', '新增', 'dev_generator_insert', '', '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-11-15 16:42:38', 1, '2020-11-15 16:42:38', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1327894837093855234, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1327894837093855234', '修改', 'dev_generator_update', '', '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 1, 1, '2020-11-15 16:42:55', 1, '2020-11-15 16:43:14', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1327894965179510785, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1327894965179510785', '删除', 'dev_generator_delete', '', '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2020-11-15 16:43:25', 1, '2020-11-15 16:43:25', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1327895061598171137, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1327895061598171137', '生成', 'dev_generator_create', '', '0', '2', NULL, NULL, NULL, 7, '0', '0', '0', 1, 1, '2020-11-15 16:43:48', 1, '2021-05-04 20:19:47', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1327903778221699074, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1327903778221699074', '同步', 'dev_generator_sync', '', '0', '2', NULL, NULL, NULL, 5, '0', '0', '0', 2, 1, '2020-11-15 17:18:27', 1, '2021-05-04 20:19:32', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1329374800267452417, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1329374800267452417', '导入数据表', 'dev_generator_import', '', '0', '2', NULL, NULL, NULL, 6, '0', '0', '0', 2, 1313694379541635074, '2020-11-19 18:43:46', 1, '2021-05-04 20:19:40', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1330365141900591105, 1327085543511293954, '0,1327085543511293954,1330365141900591105', '某系统用户', NULL, '', '0', '1', 'user', 'views/modules/gentest/user/index', NULL, 2, '0', '0', '0', 9, 1313694379541635074, '2020-11-22 12:19:01', 1, '2022-04-29 16:36:49', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1330365525440331778, 1330365141900591105, '0,1327085543511293954,1330365141900591105,1330365525440331778', '查看', 'gentest_user_select', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 6, 1313694379541635074, '2020-11-22 12:20:33', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1330365570587820033, 1330365141900591105, '0,1327085543511293954,1330365141900591105,1330365570587820033', '新增', 'gentest_user_insert', '', '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 7, 1313694379541635074, '2020-11-22 12:20:44', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1330365615181660162, 1330365141900591105, '0,1327085543511293954,1330365141900591105,1330365615181660162', '修改', 'gentest_user_update', '', '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 7, 1313694379541635074, '2020-11-22 12:20:54', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1330365717015166977, 1330365141900591105, '0,1327085543511293954,1330365141900591105,1330365717015166977', '删除', 'gentest_user_delete', '', '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 6, 1313694379541635074, '2020-11-22 12:21:19', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1332662450423635969, 1460639200696160257, '0,1460639200696160257,1332662450423635969', '组织管理', NULL, '', '0,1', '1', 'org', 'views/modules/system/orgManagement/index', NULL, 4, '0', '0', '0', 4, 1, '2020-11-28 20:27:43', 1, '2021-11-17 00:02:31', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1332662689314414594, 1332662450423635969, '0,1460639200696160257,1332662450423635969,1332662689314414594', '查看', 'system_org_select', '', '0,1', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2020-11-28 20:28:39', 1, '2020-11-28 20:28:39', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1332662758860169217, 1332662450423635969, '0,1460639200696160257,1332662450423635969,1332662758860169217', '增加', 'system_org_insert', '', '0,1', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2020-11-28 20:28:56', 1, '2020-11-28 20:28:56', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1332662809711910913, 1332662450423635969, '0,1460639200696160257,1332662450423635969,1332662809711910913', '修改', 'system_org_update', '', '0,1', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2020-11-28 20:29:08', 1, '2020-11-28 20:29:08', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1332662858294534146, 1332662450423635969, '0,1460639200696160257,1332662450423635969,1332662858294534146', '删除', 'system_org_delete', '', '0,1', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2020-11-28 20:29:20', 1, '2020-11-28 20:29:20', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1335439751687208961, 1, '0,1,1335439751687208961', '地域管理', NULL, '', '0', '1', 'area', 'views/modules/system/areaManagement/index', NULL, 8, '0', '0', '0', 3, 1313694379541635074, '2020-12-06 12:23:43', 1, '2021-04-29 13:02:44', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1335439904372457474, 1335439751687208961, '0,1,1335439751687208961,1335439904372457474', '新增', 'system_area_insert', '', '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 1, 1313694379541635074, '2020-12-06 12:24:19', 1313694379541635074, '2020-12-06 12:24:50', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1335440004809261058, 1335439751687208961, '0,1,1335439751687208961,1335440004809261058', '查看', 'system_area_select', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1313694379541635074, '2020-12-06 12:24:43', 1313694379541635074, '2020-12-06 12:24:43', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1335440081128816642, 1335439751687208961, '0,1,1335439751687208961,1335440081128816642', '修改', 'system_area_update', '', '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 1, 1313694379541635074, '2020-12-06 12:25:01', 1313694379541635074, '2020-12-06 12:25:07', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1335440153140822017, 1335439751687208961, '0,1,1335439751687208961,1335440153140822017', '删除', 'system_area_delete', '', '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1313694379541635074, '2020-12-06 12:25:18', 1313694379541635074, '2020-12-06 12:25:18', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1337719928086458369, 1330365141900591105, '0,1327085543511293954,1330365141900591105,1337719928086458369', '导出', 'gentest_user_export', '', '0', '2', NULL, NULL, NULL, 5, '0', '0', '0', 6, 1313694379541635074, '2020-12-12 19:24:19', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1337720128930705409, 1330365141900591105, '0,1327085543511293954,1330365141900591105,1337720128930705409', '导入', 'gentest_user_import', '', '0', '2', NULL, NULL, NULL, 6, '0', '0', '0', 6, 1313694379541635074, '2020-12-12 19:25:07', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1337796232345407489, 1327085856930660353, '0,1327085543511293954,1327085856930660353,1337796232345407489', '导出', 'gentest_test_export', '', '0', '2', NULL, NULL, NULL, 5, '0', '0', '0', 6, 1313694379541635074, '2020-12-13 00:27:31', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1337796311940714498, 1327085856930660353, '0,1327085543511293954,1327085856930660353,1337796311940714498', '导入', 'gentest_test_import', '', '0', '2', NULL, NULL, NULL, 6, '0', '0', '0', 6, 1313694379541635074, '2020-12-13 00:27:50', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1340626549594677250, 1327085543511293954, '0,1327085543511293954,1340626549594677250', '汽车信息', NULL, '', '0', '1', 'carinfo', 'views/modules/gentest/carinfo/index', NULL, 3, '0', '0', '0', 9, 1313694379541635074, '2020-12-20 19:54:12', 1, '2022-04-29 16:36:49', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1340626612895113217, 1340626549594677250, '0,1327085543511293954,1340626549594677250,1340626612895113217', '查看', 'gentest_carinfo_select', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 6, 1313694379541635074, '2020-12-20 19:54:27', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1340626666078887937, 1340626549594677250, '0,1327085543511293954,1340626549594677250,1340626666078887937', '新增', 'gentest_carinfo_insert', '', '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 6, 1313694379541635074, '2020-12-20 19:54:39', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1340626895356321793, 1340626549594677250, '0,1327085543511293954,1340626549594677250,1340626895356321793', '修改', 'gentest_carinfo_update', '', '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 6, 1313694379541635074, '2020-12-20 19:55:34', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1340626939119689729, 1340626549594677250, '0,1327085543511293954,1340626549594677250,1340626939119689729', '删除', 'gentest_carinfo_delete', '', '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 6, 1313694379541635074, '2020-12-20 19:55:45', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1340626988251766786, 1340626549594677250, '0,1327085543511293954,1340626549594677250,1340626988251766786', '导入', 'gentest_carinfo_import', '', '0', '2', NULL, NULL, NULL, 5, '0', '0', '0', 6, 1313694379541635074, '2020-12-20 19:55:56', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1340627032942075906, 1340626549594677250, '0,1327085543511293954,1340626549594677250,1340627032942075906', '导出', 'gentest_carinfo_export', '', '0', '2', NULL, NULL, NULL, 6, '0', '0', '0', 7, 1313694379541635074, '2020-12-20 19:56:07', 1, '2022-04-29 16:36:49', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1351012936860155906, 1314610817013919745, '0,1314610817013919745,1351012936860155906', '系统监控', NULL, '', '0', '1', 'sysmonitor', 'views/modules/system/monitorManagement/index', NULL, 1, '0', '0', '0', 1, 1313694379541635074, '2021-01-18 11:45:59', 1313694379541635074, '2021-01-18 11:47:15', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1351013587816136705, 1351012936860155906, '0,1314610817013919745,1351012936860155906,1351013587816136705', '查看', 'devops_sysmonitor_select', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2021-01-18 11:48:35', 1, '2021-01-18 11:48:35', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1360233188433977345, 1, '0,1,1360233188433977345', '系统设置', NULL, '', '0', '1', 'set', 'views/modules/system/setManagement/index', NULL, 99, '0', '0', '0', 4, 1313694379541635074, '2021-02-12 22:23:59', 1, '2021-04-29 13:01:24', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1360233383397810177, 1360233188433977345, '0,1,1360233188433977345,1360233383397810177', '更新', 'system_options_update', '', '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 2, 1313694379541635074, '2021-02-12 22:24:45', 1313694379541635074, '2021-02-14 01:37:07', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1370051609388388353, 3, '0,1460639200696160257,3,1370051609388388353', '重置密码', 'system_user_resetPassword', '', '0,1', '2', NULL, NULL, NULL, 10, '0', '0', '0', 1, 1, '2021-03-12 00:38:53', 1, '2021-03-12 00:39:04', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1370404146704654337, 3, '0,1460639200696160257,3,1370404146704654337', '变更账户状态', 'system_user_enable', '', '0,1', '2', NULL, NULL, NULL, 11, '0', '0', '0', 2, 1, '2021-03-12 23:59:44', 1, '2021-04-08 23:59:33', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1380173787882696705, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1380173787882696705', '变更租户状态', 'system_tenant_enable', '', '0', '2', NULL, NULL, NULL, 5, '0', '0', '0', 0, 1, '2021-04-08 23:00:48', 1, '2021-04-08 23:00:48', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1387633500164599809, 1, '0,1,1387633500164599809', '参数配置', NULL, '', '0', '1', 'options', 'views/modules/system/optionsManagement/index', NULL, 7, '0', '0', '0', 2, 1, '2021-04-29 13:03:02', 1, '2021-04-29 13:03:39', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1387633799226863618, 1387633500164599809, '0,1,1387633500164599809,1387633799226863618', '查看', 'system_options_select', NULL, '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 2, 1, '2021-04-29 13:04:13', 1, '2021-04-29 13:07:10', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1387633960401383426, 1387633500164599809, '0,1,1387633500164599809,1387633960401383426', '新增', 'system_options_insert', NULL, '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 1, 1, '2021-04-29 13:04:52', 1, '2021-04-29 13:07:15', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1387634089447534594, 1387633500164599809, '0,1,1387633500164599809,1387634089447534594', '修改', 'system_options_update', NULL, '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 1, 1, '2021-04-29 13:05:23', 1, '2021-04-29 13:07:19', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1387634157474951169, 1387633500164599809, '0,1,1387633500164599809,1387634157474951169', '删除', 'system_options_delete', NULL, '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 1, 1, '2021-04-29 13:05:39', 1, '2021-04-29 13:07:23', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1389555212654223361, 1327893773049262082, '0,1314068325453574145,1397807288445526017,1327893773049262082,1389555212654223361', '生成菜单', 'dev_generator_createMenu', NULL, '0', '2', NULL, NULL, NULL, 8, '0', '0', '0', 1, 1, '2021-05-04 20:19:14', 1, '2021-05-04 20:19:52', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1397807288445526017, 1314068325453574145, '0,1314068325453574145,1397807288445526017', '开发向导', NULL, '', '0', '1', 'generator', 'EmptyLayout', NULL, 1, '1', '0', '0', 2, 1, '2021-05-27 14:50:02', 1, '2021-05-27 15:02:49', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1397807399338729473, 1397807288445526017, '0,1314068325453574145,1397807288445526017,1397807399338729473', '代码模板', NULL, NULL, '0', '1', 'template', 'views/modules/generator/template/index', NULL, 2, '0', '0', '0', 2, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:54', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1397807399363895298, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1397807399363895298', '查看', 'generator_template_select', NULL, '0', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:29', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1397807399389061121, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1397807399389061121', '新增', 'generator_template_insert', NULL, '0', '2', NULL, NULL, NULL, 2, '0', '0', '0', 0, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:29', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1397807399414226945, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1397807399414226945', '修改', 'generator_template_update', NULL, '0', '2', NULL, NULL, NULL, 3, '0', '0', '0', 0, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:29', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1397807399439392770, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1397807399439392770', '删除', 'generator_template_delete', NULL, '0', '2', NULL, NULL, NULL, 4, '0', '0', '0', 0, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:29', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1397807399456169985, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1397807399456169985', '导入', 'generator_template_import', NULL, '0', '2', NULL, NULL, NULL, 5, '0', '0', '0', 0, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:29', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1397807399481335810, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1397807399481335810', '导出', 'generator_template_export', NULL, '0', '2', NULL, NULL, NULL, 6, '0', '0', '0', 0, 1, '2021-05-27 14:50:29', 1, '2021-05-27 14:50:29', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1399667141430452225, 1397807399338729473, '0,1314068325453574145,1397807288445526017,1397807399338729473,1399667141430452225', '复制', 'generator_template_copy', NULL, '0', '2', NULL, NULL, NULL, 7, '0', '0', '0', 0, 1, '2021-06-01 18:00:26', 1, '2021-06-01 18:00:26', '2022-04-29 17:30:23'); +INSERT INTO `sys_menu` VALUES (1448537070279237634, 4, '0,1460639200696160257,4,1448537070279237634', '设置数据权限', 'system_role_setDataPerms', NULL, '0,1', '2', NULL, NULL, NULL, 6, '0', '0', '0', 0, 1, '2021-10-14 14:32:05', 1, '2021-10-14 14:32:05', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1460629524738764802, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1460629524738764802', '设置管理用户', 'system_set_tenant_admin', NULL, '0', '2', NULL, NULL, NULL, 6, '0', '0', '0', 0, 1, '2021-11-16 23:23:11', 1, '2021-11-16 23:23:11', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1460639200696160257, 0, '0,1460639200696160257', '组织机构', NULL, 'users', '0,1', '1', '/org', 'Layout', NULL, 2, '1', '0', '0', 5, 1, '2021-11-17 00:01:37', 1, '2021-11-30 17:10:45', '2022-04-29 17:22:11'); +INSERT INTO `sys_menu` VALUES (1465587677695479810, 3, '0,1460639200696160257,3,1465587677695479810', '授权组织', 'system_user_setOrg', NULL, '0,1', '2', NULL, NULL, NULL, 8, '0', '0', '0', 1, 1, '2021-11-30 15:45:06', 1, '2021-11-30 15:45:29', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621050623209474, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621050623209474', '增加管理用户', 'system_user_insert', NULL, '0', '2', NULL, NULL, NULL, 7, '0', '0', '0', 0, 1, '2021-11-30 17:57:43', 1, '2021-11-30 17:57:43', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621206781341698, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621206781341698', '修改管理用户', 'system_user_update', NULL, '0', '2', NULL, NULL, NULL, 8, '0', '0', '0', 0, 1, '2021-11-30 17:58:20', 1, '2021-11-30 17:58:20', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621319830417409, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621319830417409', '删除管理用户', 'system_user_delete', NULL, '0', '2', NULL, NULL, NULL, 9, '0', '0', '0', 0, 1, '2021-11-30 17:58:47', 1, '2021-11-30 17:58:47', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621468124229634, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621468124229634', '修改管理用户密码', 'system_user_updatePassword', NULL, '0', '2', NULL, NULL, NULL, 10, '0', '0', '0', 0, 1, '2021-11-30 17:59:23', 1, '2021-11-30 17:59:23', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621601087860738, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621601087860738', '重置管理用户密码', 'system_user_resetPassword', NULL, '0', '2', NULL, NULL, NULL, 11, '0', '0', '0', 0, 1, '2021-11-30 17:59:54', 1, '2021-11-30 17:59:54', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621733564952578, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621733564952578', '变更管理用户状态', 'system_user_enable', NULL, '0', '2', NULL, NULL, NULL, 12, '0', '0', '0', 0, 1, '2021-11-30 18:00:26', 1, '2021-11-30 18:00:26', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1465621843787067394, 1315201380721446914, '0,1460639200696160257,1315201380721446914,1465621843787067394', '授权管理用户角色', 'system_user_setRole', NULL, '0', '2', NULL, NULL, NULL, 13, '0', '0', '0', 0, 1, '2021-11-30 18:00:52', 1, '2021-11-30 18:00:52', '2022-04-29 17:29:44'); +INSERT INTO `sys_menu` VALUES (1504776412970254338, 0, '0,1504776412970254338', '日志监控', NULL, 'file-contract', '0,1', '1', '/log', 'Layout', NULL, 98, '0', '0', '0', 1, 1, '2022-03-18 19:07:09', 1, '2022-03-18 19:07:22', '2022-04-29 17:22:11'); +INSERT INTO `sys_menu` VALUES (1504779965155655682, 1504776412970254338, '0,1504776412970254338,1504779965155655682', '登录日志', NULL, '', '0,1', '1', 'login-logs', 'views/modules/system/loginLogsManagement/index', NULL, 1, '0', '0', '0', 1, 1, '2022-03-18 19:21:16', 1, '2022-03-18 19:21:40', '2022-04-29 17:28:43'); +INSERT INTO `sys_menu` VALUES (1504780214448308226, 1504779965155655682, '0,1504776412970254338,1504779965155655682,1504780214448308226', '查看', 'devops_login_logs_select', NULL, '0,1', '2', NULL, NULL, NULL, 1, '0', '0', '0', 0, 1, '2022-03-18 19:22:15', 1, '2022-03-18 19:22:15', '2022-04-29 17:29:44'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_options +-- ---------------------------- +DROP TABLE IF EXISTS `sys_options`; +CREATE TABLE `sys_options` ( + `id` bigint(19) NOT NULL COMMENT '唯一主键', + `option_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '参数编号', + `option_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '参数名称', + `option_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '参数值', + `iz_lock` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否内置 0否 1是', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `version` int(11) NOT NULL DEFAULT '0' COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `index` (`option_code`) USING BTREE COMMENT '参数编号唯一' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统参数表'; + +-- ---------------------------- +-- Records of sys_options +-- ---------------------------- +BEGIN; +INSERT INTO `sys_options` VALUES (1, 'crypto_asymmetric', '非对称加解密算法', 'RSA', '1', NULL, 0, 1, '2021-02-10 23:19:35', 1313694379541635074, '2021-04-04 11:19:26', '2021-04-29 11:11:40'); +INSERT INTO `sys_options` VALUES (2, 'crypto_asymmetric_public_key', '非对称加解密-公钥', 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQS75ZTYUL6IJJBgylgFDtksWZx4OsVK5CBJGXi3n9LON1Jg7KsxkgindCD28gQRIEh6ZP1IuhlMs9N/QteRbM3b1oDKW7Cbr7lFk+EYUmpO5nwD1+IHowiNc0AK+XfICOVF5287wE4LFLqBDnWhV0WNQFjYYpAc7852ZfEwThSQIDAQAB', '1', NULL, 0, 1, '2021-02-10 23:19:35', 1313694379541635074, '2021-04-04 11:19:26', '2021-04-29 11:11:41'); +INSERT INTO `sys_options` VALUES (3, 'crypto_asymmetric_private_key', '非对称加解密-私钥', 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJBLvllNhQvogkkGDKWAUO2SxZnHg6xUrkIEkZeLef0s43UmDsqzGSCKd0IPbyBBEgSHpk/Ui6GUyz039C15FszdvWgMpbsJuvuUWT4RhSak7mfAPX4gejCI1zQAr5d8gI5UXnbzvATgsUuoEOdaFXRY1AWNhikBzvznZl8TBOFJAgMBAAECgYAJvtCmFi7RK6ysIxhBj6JnmTN24ltJpuJ2zpL8Sc0J+B+LyIk6z9CROqjS5L+PM+kN0BEmCedwTBNTf1VV3BXzbPcX/prE004LXcbv5mjgaHf/PybzJQumYM5MuD9dJYBLc1PUNu2b9eGekEU+vzn0HCnmAkfwU7FCdU7Nh8/ZnQJBAMkY/nzYxue0rdfD4ZybM8chBksp9EA8mwmCW/PosJGJ6YVJ913PbfovYuSG4rwm0Ew6i/1zcXvAFjt5dW+L5EsCQQC3sMq5EF4Bfils0dTdn8Pwtv2t3H6wwaAc9QAExHYtZ5pipFH9NXiWn6KUJYq28mRxxKtfoara/8Ahb5yHY0w7AkEArGnmfyno123cgppqC7gxW3AgEj+FL7IGhs+igOumvxFMCsBQ+rhGpXMNSbuwF/r7KfAkaAgbaytUpGdNXXbGIwJAas7uoXsl3iJYvgCokJFkYmRUzzJlrCt6CTxgXWVK/g2+1FqNnfjofFSoORI3PTdmNkzQBRRA/4Q0WHzIfGS9nwJBAMLXrVKH6uhn67dwXKRCy2Xt54dLEtL43jL+xzWeHJibSkSyImLiAn1n2imSpB6ubJnBuvH19Y0nOXKBP0+VDGA=', '1', NULL, 0, 1, '2021-02-10 23:19:35', 1313694379541635074, '2021-04-04 11:19:26', '2021-04-29 11:11:41'); +INSERT INTO `sys_options` VALUES (4, 'def_pass', '系统默认密码', 'Aa123456.', '1', NULL, 2, 1, '2021-02-10 23:19:35', 1313694379541635074, '2021-10-15 16:24:06', '2021-10-15 16:22:23'); +INSERT INTO `sys_options` VALUES (5, 'def_role', '系统默认角色编号', '007', '1', NULL, 2, 1, '2021-02-10 23:19:35', 1313694379541635074, '2021-10-15 16:24:06', '2021-10-15 16:22:23'); +INSERT INTO `sys_options` VALUES (1387687830355902465, 'email_account', '邮箱账号', 'meet.edwin@foxmail.com', '1', NULL, 40, 1, '2021-04-29 16:38:55', 1, '2022-08-01 19:02:53', '2022-08-01 19:02:52'); +INSERT INTO `sys_options` VALUES (1387687830523674626, 'email_password', '邮箱密码', 'kwxibcxostgqbbgf', '1', NULL, 40, 1, '2021-04-29 16:38:55', 1, '2022-08-01 19:02:53', '2022-08-01 19:02:52'); +INSERT INTO `sys_options` VALUES (1387687830586589186, 'email_addresser', '发件人', 'OPSLI 快速开发平台', '1', NULL, 40, 1, '2021-04-29 16:38:55', 1, '2022-08-01 19:02:53', '2022-08-01 19:02:52'); +INSERT INTO `sys_options` VALUES (1387692123406348289, 'email_smtp', 'SMTP地址', 'smtp.qq.com', '1', NULL, 31, 1, '2021-04-29 16:55:59', 1, '2022-08-01 19:02:53', '2022-08-01 19:02:52'); +INSERT INTO `sys_options` VALUES (1387695264482865154, 'email_port', 'SMTP端口', '465', '1', NULL, 23, 1, '2021-04-29 17:08:28', 1, '2022-08-01 19:02:53', '2022-08-01 19:02:52'); +INSERT INTO `sys_options` VALUES (1387700400634605569, 'email_ssl_enable', '开启SSL认证', '1', '1', NULL, 19, 1313694379541635074, '2021-04-29 17:28:52', 1, '2022-08-01 19:02:53', '2022-08-01 19:02:52'); +INSERT INTO `sys_options` VALUES (1388129689385472001, 'storage_local_domain', 'storage_local_domain', 'http://127.0.0.1:8080/opsli-boot', '1', NULL, 0, 1313694379541635074, '2021-04-30 21:54:43', 1313694379541635074, '2021-04-30 21:54:43', '2021-04-30 21:54:42'); +INSERT INTO `sys_options` VALUES (1388129689523884033, 'storage_local_path_prefix', 'storage_local_path_prefix', '', '1', NULL, 0, 1313694379541635074, '2021-04-30 21:54:43', 1313694379541635074, '2021-04-30 21:54:43', '2021-04-30 21:54:42'); +INSERT INTO `sys_options` VALUES (1388327975470596098, 'storage_type', 'storage_type', 'upYun', '1', NULL, 2, 1313694379541635074, '2021-05-01 11:02:38', 1313694379541635074, '2021-10-15 16:24:06', '2021-10-15 16:22:23'); +INSERT INTO `sys_options` VALUES (1388333266843320322, '11', '111', '111', '0', NULL, 0, 1313694379541635074, '2021-05-01 11:23:39', 1313694379541635074, '2021-05-01 11:23:39', '2021-05-01 11:23:39'); +INSERT INTO `sys_options` VALUES (1388333321180528642, '222', '222', '222', '0', NULL, 0, 1313694379541635074, '2021-05-01 11:23:52', 1313694379541635074, '2021-05-01 11:23:52', '2021-05-01 11:23:52'); +INSERT INTO `sys_options` VALUES (1388333452273500161, '333', '333', '333', '0', NULL, 0, 1313694379541635074, '2021-05-01 11:24:24', 1313694379541635074, '2021-05-01 11:24:24', '2021-05-01 11:24:23'); +INSERT INTO `sys_options` VALUES (1388333500516384770, '444', '444', '444', '0', NULL, 0, 1313694379541635074, '2021-05-01 11:24:35', 1313694379541635074, '2021-05-01 11:24:35', '2021-05-01 11:24:35'); +INSERT INTO `sys_options` VALUES (1400402255261159426, 'storage_upyun_domain', 'storage_upyun_domain', 'http://upload.bedebug.com', '1', NULL, 3, 1, '2021-06-03 18:41:31', 1, '2021-06-03 19:47:51', '2021-06-03 19:47:51'); +INSERT INTO `sys_options` VALUES (1400402255261159427, 'storage_upyun_path_prefix', 'storage_upyun_path_prefix', '', '1', NULL, 3, 1, '2021-06-03 18:41:31', 1, '2021-06-03 19:47:51', '2021-06-03 19:47:51'); +INSERT INTO `sys_options` VALUES (1400402255328268290, 'storage_upyun_bucket_name', 'storage_upyun_bucket_name', 'opsli-storage', '1', NULL, 3, 1, '2021-06-03 18:41:31', 1, '2021-06-03 19:47:51', '2021-06-03 19:47:51'); +INSERT INTO `sys_options` VALUES (1400402255328268291, 'storage_upyun_username', 'storage_upyun_username', 'opsli', '1', NULL, 3, 1, '2021-06-03 18:41:31', 1, '2021-06-03 19:47:51', '2021-06-03 19:47:51'); +INSERT INTO `sys_options` VALUES (1400402255328268292, 'storage_upyun_password', 'storage_upyun_password', 'DjWrspmr4UbfBdnkrgm4ssCOVK7rUTXF', '1', NULL, 3, 1, '2021-06-03 18:41:31', 1, '2021-06-03 19:47:51', '2021-06-03 19:47:51'); +INSERT INTO `sys_options` VALUES (1504319856055046145, '123321', '123132', NULL, '0', NULL, 6, 1465171199435362305, '2022-03-17 12:52:57', 1, '2022-07-25 19:57:13', '2022-07-25 19:57:13'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_org +-- ---------------------------- +DROP TABLE IF EXISTS `sys_org`; +CREATE TABLE `sys_org` ( + `id` bigint(19) NOT NULL COMMENT '字典主键', + `parent_id` bigint(19) NOT NULL DEFAULT '0' COMMENT '父级主键', + `parent_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '父级主键集合', + `org_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '组织机构组', + `org_code` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织机构编号', + `org_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织机构名称', + `sort_no` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `tenant_id` bigint(20) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除标记:0未删除,1删除', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` bigint(19) NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `org_index` (`org_code`,`org_name`) USING BTREE, + KEY `pid` (`parent_id`) USING BTREE COMMENT '上级id', + KEY `pids` (`parent_ids`) USING BTREE COMMENT '上级id集合', + KEY `org_ids` (`org_ids`) USING BTREE COMMENT '组织id集合' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='组织机构表'; + +-- ---------------------------- +-- Records of sys_org +-- ---------------------------- +BEGIN; +INSERT INTO `sys_org` VALUES (1332710973848449026, 0, '0', '0,1332710973848449026', '0011', 'A公司', 1, NULL, 1, '0', 11, 1313694379541635074, '2020-11-28 23:40:31', 1, '2021-06-08 11:38:29', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1332878633177477122, 0, '0', '0,1332878633177477122', '0013', 'C公司', 3, NULL, 1, '0', 10, 1313694379541635074, '2020-11-29 10:46:44', 1, '2021-06-07 19:52:59', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1332879851278856193, 1332710973848449026, '0,1332710973848449026', '0,1332710973848449026,1332879851278856193', '0011_123', 'A公司B部门', 1, NULL, 1, '0', 6, 1313694379541635074, '2020-11-29 10:51:35', 1313694379541635074, '2021-02-25 13:31:17', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1332880775317581826, 1332879851278856193, '0,1332710973848449026,1332879851278856193', '0,1332710973848449026,1332879851278856193,1332880775317581826', '0011_123_003', '测试岗', 1, NULL, 1, '0', 5, 1313694379541635074, '2020-11-29 10:55:15', 1313694379541635074, '2021-02-25 13:30:51', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1336209704187879425, 0, '0', '0,1336209704187879425', '0012', 'B公司', 2, NULL, 1, '0', 3, 1313694379541635074, '2020-12-08 15:23:14', 1, '2021-01-11 19:19:51', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1401861234604605441, 0, '0', '0,1401861234604605441', '12334', 'D公司', 1, NULL, 1, '0', 0, 1, '2021-06-07 19:18:58', 1, '2021-06-07 19:18:58', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1401861575953842177, 1401861234604605441, '0,1401861234604605441', '0,1401861234604605441,1401861575953842177', '12334_111', 'D公司的XXX部门', 1, NULL, 1, '0', 0, 1, '2021-06-07 19:20:20', 1, '2021-06-07 19:20:20', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1401861991370293250, 1401873907685687297, '0,1401861234604605441,1401861575953842177,1401873907685687297', '0,1401861234604605441,1401861575953842177,1401873907685687297,1401861991370293250', '12334_111_111', '不知道哪儿个岗位', 1, NULL, 1, '0', 12, 1, '2021-06-07 19:21:59', 1, '2021-10-14 16:26:18', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1401873858511667201, 0, '0', '0,1401873858511667201', '123123', 'E公司', 1, NULL, 1, '0', 1, 1, '2021-06-07 20:09:08', 1313694379541635074, '2021-11-30 18:04:56', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1401873907685687297, 1401861575953842177, '0,1401861234604605441,1401861575953842177', '0,1401861234604605441,1401861575953842177,1401873907685687297', '123123_123', '123', 1, '123333', 1, '0', 1, 1, '2021-06-07 20:09:20', 1, '2021-10-14 16:26:18', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1448921834744115202, 1401873907685687297, '0,1401861234604605441,1401861575953842177,1401873907685687297', '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921834744115202', '123123_123_1212', '啊啊啊啊', 2, NULL, 1, '0', 0, 1, '2021-10-15 16:01:00', 1, '2021-10-15 16:01:00', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1448921889865658369, 1401873907685687297, '0,1401861234604605441,1401861575953842177,1401873907685687297', '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921889865658369', '123123_123_12312344', '测试测试', 3, NULL, 1, '0', 0, 1, '2021-10-15 16:01:13', 1, '2021-10-15 16:01:13', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1465586952575815681, 0, '0', '0,1465586952575815681', 'xxxx', 'XXXX集团', 1, NULL, 0, '0', 0, 1, '2021-11-30 15:42:13', 1, '2021-11-30 15:42:13', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1465587033538465793, 1465586952575815681, '0,1465586952575815681', '0,1465586952575815681,1465587033538465793', 'xxxx_bj', '北京子公司', 1, NULL, 0, '0', 0, 1, '2021-11-30 15:42:33', 1, '2021-11-30 15:42:33', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1465587103902109698, 1465586952575815681, '0,1465586952575815681', '0,1465586952575815681,1465587103902109698', 'xxxx_sh', '上海子公司', 2, NULL, 0, '0', 0, 1, '2021-11-30 15:42:50', 1, '2021-11-30 15:42:50', '2021-12-01 13:03:45'); +INSERT INTO `sys_org` VALUES (1465973116898017281, 1401861575953842177, '0,1401861234604605441,1401861575953842177', '0,1401861234604605441,1401861575953842177,1465973116898017281', '12334_111_13334', 'XXX开发组', 2, NULL, 1, '0', 0, 1465886867659096066, '2021-12-01 17:16:42', 1465886867659096066, '2021-12-01 17:16:42', '2021-12-01 17:14:30'); +INSERT INTO `sys_org` VALUES (1465996676186124290, 1401861575953842177, '0,1401861234604605441,1401861575953842177', '0,1401861234604605441,1401861575953842177,1465996676186124290', '12334_111_43223', '测试组', 3, NULL, 1, '0', 0, 1465886867659096066, '2021-12-01 18:50:19', 1465886867659096066, '2021-12-01 18:50:19', '2021-12-01 18:48:05'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `id` bigint(19) NOT NULL COMMENT '角色主键', + `role_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色编码', + `role_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色名称', + `label` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '标签', + `data_scope` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '授权数据范围', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `tenant_id` bigint(20) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `role_code` (`role_code`,`role_name`,`tenant_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='角色信息表'; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +BEGIN; +INSERT INTO `sys_role` VALUES (2, '001', '管理员', '0', '3', '', 0, '0', 14, 1, '2018-12-09 17:48:13', 1, '2021-11-30 15:50:36', '2021-11-30 15:48:21'); +INSERT INTO `sys_role` VALUES (1448924556381843458, '001', '职员', '1', '0', NULL, 1, '0', 1, 1313694379541635074, '2021-10-15 16:11:49', 1313694379541635074, '2021-10-15 17:16:27', '2021-11-29 18:13:29'); +INSERT INTO `sys_role` VALUES (1448924616192618497, '002', '业务员', '1', '1', NULL, 1, '0', 1, 1313694379541635074, '2021-10-15 16:12:03', 1313694379541635074, '2021-10-15 17:16:37', '2021-11-29 18:13:31'); +INSERT INTO `sys_role` VALUES (1448924680386441217, '003', '部门负责人', '1', '2', NULL, 1, '0', 2, 1313694379541635074, '2021-10-15 16:12:18', 1313694379541635074, '2021-10-15 17:16:56', '2021-11-29 18:13:32'); +INSERT INTO `sys_role` VALUES (1448924738452385794, '004', '管理员', '1', '3', NULL, 1, '0', 3, 1313694379541635074, '2021-10-15 16:12:32', 1313694379541635074, '2021-11-30 18:04:50', '2021-11-30 18:02:35'); +INSERT INTO `sys_role` VALUES (1463431580473810945, '1111', '默认租户角色', '1', '3', NULL, 0, '0', 1, 1, '2021-11-24 16:57:33', 1, '2021-11-29 11:42:18', '2021-11-29 11:40:02'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_role_menu_ref +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menu_ref`; +CREATE TABLE `sys_role_menu_ref` ( + `id` bigint(19) NOT NULL COMMENT '用户角色关联', + `menu_id` bigint(19) NOT NULL COMMENT '用户主键', + `role_id` bigint(19) NOT NULL COMMENT '角色主键', + PRIMARY KEY (`id`) USING BTREE, + KEY `sys_role_menu` (`menu_id`,`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='角色功能关联表'; + +-- ---------------------------- +-- Records of sys_role_menu_ref +-- ---------------------------- +BEGIN; +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099213, 1, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1312770352622878721, 1, 1312770323526991874); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375172, 3, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200001, 3, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403012, 3, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1312770352614490113, 4, 1312770323526991874); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403023, 4, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075793, 1312756531833356289, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375174, 1313789204920131585, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200003, 1313789204920131585, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403014, 1313789204920131585, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375175, 1313789308506857474, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200004, 1313789308506857474, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403015, 1313789308506857474, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375176, 1313789400169177089, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200005, 1313789400169177089, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403016, 1313789400169177089, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375177, 1313789529840279554, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200006, 1313789529840279554, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403017, 1313789529840279554, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375173, 1313806847370620930, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200002, 1313806847370620930, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403013, 1313806847370620930, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375178, 1313864645827678210, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200007, 1313864645827678210, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403018, 1313864645827678210, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375179, 1313864777918894082, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200008, 1313864777918894082, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403019, 1313864777918894082, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403024, 1313867061172195330, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403025, 1313867122731995137, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403026, 1313867360502894594, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403027, 1313867409949544450, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075794, 1313867556498526209, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075796, 1313867617949274113, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075797, 1313867682814185474, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075798, 1313867732508299265, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403028, 1313885644824522754, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075777, 1314066547072872450, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974880428034, 1314066547072872450, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960386, 1314066547072872450, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375170, 1314066547072872450, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325360091137, 1314066547072872450, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316080488449, 1314066547072872450, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075778, 1314066863436640258, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974880428035, 1314066863436640258, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960387, 1314066863436640258, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375171, 1314066863436640258, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325360091138, 1314066863436640258, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403010, 1314066863436640258, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075820, 1314068325453574145, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990356, 1314071137365307394, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990357, 1314074765178187777, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990358, 1314075128635600897, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990359, 1314075267769053186, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990360, 1314075542684708865, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990361, 1314075764852797442, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990362, 1314075970382082050, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990363, 1314076169481498625, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990364, 1314076280542474242, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990365, 1314076678317682689, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990366, 1314077008057085954, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990367, 1314077108560998402, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990368, 1314077229235318786, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990369, 1314077399507283970, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990370, 1314077518340304897, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990371, 1314077631905280001, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990372, 1314077729003417602, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990373, 1314120834868060162, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990374, 1314121004749955073, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990375, 1314121200103858178, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990376, 1314121675192672257, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990377, 1314121808793837570, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990378, 1314121928784486402, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990379, 1314122020136427521, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099201, 1314122123047870466, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990380, 1314122353273217025, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099202, 1314122457908518914, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099203, 1314122556776652802, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099204, 1314122628184678401, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099205, 1314122717041008641, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099206, 1314123071354839041, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099207, 1314123272790482945, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099208, 1314123690283114498, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099209, 1314123894637993985, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099210, 1314123990633029633, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099211, 1314124102365093890, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075816, 1314610817013919745, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075814, 1314616518671085570, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511897, 1314616518671085570, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075815, 1314782679522099201, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511898, 1314782679522099201, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990355, 1314786106243301378, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075819, 1314799744349913090, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075795, 1314884045724717057, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075779, 1315201380721446914, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075780, 1315201734892670977, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075781, 1315201809668722690, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075782, 1315201864219840513, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075783, 1315201925477650433, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974880428036, 1327085543511293954, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960388, 1327085543511293954, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375188, 1327085543511293954, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200017, 1327085543511293954, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403035, 1327085543511293954, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974880428037, 1327085856930660353, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960389, 1327085856930660353, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375189, 1327085856930660353, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200018, 1327085856930660353, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403036, 1327085856930660353, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974880428038, 1327086205548625921, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960390, 1327086205548625921, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375190, 1327086205548625921, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200019, 1327086205548625921, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511874, 1327086205548625921, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974880428039, 1327086298750255105, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960391, 1327086298750255105, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375191, 1327086298750255105, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200020, 1327086298750255105, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511875, 1327086298750255105, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342594, 1327086378794352642, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960392, 1327086378794352642, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375192, 1327086378794352642, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200021, 1327086378794352642, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511876, 1327086378794352642, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342595, 1327086433609711617, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960393, 1327086433609711617, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375193, 1327086433609711617, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200022, 1327086433609711617, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511877, 1327086433609711617, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990338, 1327893773049262082, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990339, 1327894701135491073, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990340, 1327894767283859457, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990341, 1327894837093855234, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990342, 1327894965179510785, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990345, 1327895061598171137, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990343, 1327903778221699074, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990344, 1329374800267452417, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342598, 1330365141900591105, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960396, 1330365141900591105, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375196, 1330365141900591105, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200025, 1330365141900591105, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511880, 1330365141900591105, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342599, 1330365525440331778, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960397, 1330365525440331778, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375197, 1330365525440331778, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200026, 1330365525440331778, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511881, 1330365525440331778, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342600, 1330365570587820033, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960398, 1330365570587820033, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375198, 1330365570587820033, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200027, 1330365570587820033, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511882, 1330365570587820033, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342601, 1330365615181660162, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960399, 1330365615181660162, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375199, 1330365615181660162, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200028, 1330365615181660162, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511883, 1330365615181660162, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342602, 1330365717015166977, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960400, 1330365717015166977, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375200, 1330365717015166977, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200029, 1330365717015166977, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511884, 1330365717015166977, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375183, 1332662450423635969, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200012, 1332662450423635969, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403030, 1332662450423635969, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375184, 1332662689314414594, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200013, 1332662689314414594, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403031, 1332662689314414594, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375185, 1332662758860169217, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200014, 1332662758860169217, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403032, 1332662758860169217, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375186, 1332662809711910913, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200015, 1332662809711910913, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403033, 1332662809711910913, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375187, 1332662858294534146, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200016, 1332662858294534146, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403034, 1332662858294534146, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075804, 1335439751687208961, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075806, 1335439904372457474, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075805, 1335440004809261058, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075807, 1335440081128816642, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075808, 1335440153140822017, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342603, 1337719928086458369, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910942457858, 1337719928086458369, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375201, 1337719928086458369, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200030, 1337719928086458369, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511885, 1337719928086458369, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342604, 1337720128930705409, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846466, 1337720128930705409, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375202, 1337720128930705409, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200031, 1337720128930705409, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511886, 1337720128930705409, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342596, 1337796232345407489, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960394, 1337796232345407489, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375194, 1337796232345407489, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200023, 1337796232345407489, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511878, 1337796232345407489, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342597, 1337796311940714498, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910866960395, 1337796311940714498, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375195, 1337796311940714498, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200024, 1337796311940714498, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511879, 1337796311940714498, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342605, 1340626549594677250, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846467, 1340626549594677250, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375203, 1340626549594677250, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200032, 1340626549594677250, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511887, 1340626549594677250, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342606, 1340626612895113217, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846468, 1340626612895113217, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375204, 1340626612895113217, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200033, 1340626612895113217, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511888, 1340626612895113217, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342607, 1340626666078887937, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846469, 1340626666078887937, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375205, 1340626666078887937, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200034, 1340626666078887937, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511889, 1340626666078887937, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342608, 1340626895356321793, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846470, 1340626895356321793, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375206, 1340626895356321793, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200035, 1340626895356321793, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511890, 1340626895356321793, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342609, 1340626939119689729, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846471, 1340626939119689729, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375207, 1340626939119689729, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200036, 1340626939119689729, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511891, 1340626939119689729, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342610, 1340626988251766786, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846472, 1340626988251766786, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375208, 1340626988251766786, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200037, 1340626988251766786, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511892, 1340626988251766786, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1448926974943342611, 1340627032942075906, 1448924556381843458); +INSERT INTO `sys_role_menu_ref` VALUES (1448926910950846473, 1340627032942075906, 1448924616192618497); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375209, 1340627032942075906, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200038, 1340627032942075906, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511893, 1340627032942075906, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075817, 1351012936860155906, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075818, 1351013587816136705, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075809, 1360233188433977345, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075810, 1360233383397810177, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375181, 1370051609388388353, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200010, 1370051609388388353, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403021, 1370051609388388353, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375182, 1370404146704654337, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200011, 1370404146704654337, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403022, 1370404146704654337, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075784, 1380173787882696705, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075799, 1387633500164599809, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075800, 1387633799226863618, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075801, 1387633960401383426, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075802, 1387634089447534594, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075803, 1387634157474951169, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990346, 1389555212654223361, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990337, 1397807288445526017, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990347, 1397807399338729473, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990348, 1397807399363895298, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990349, 1397807399389061121, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990350, 1397807399414226945, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990351, 1397807399439392770, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990352, 1397807399456169985, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990353, 1397807399481335810, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836894990354, 1399667141430452225, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403029, 1448537070279237634, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075785, 1460629524738764802, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836962099212, 1460639200696160257, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375210, 1460639200696160257, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200039, 1460639200696160257, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403011, 1460639200696160257, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1465888361674375180, 1465587677695479810, 1448924680386441217); +INSERT INTO `sys_role_menu_ref` VALUES (1465888325427200009, 1465587677695479810, 1448924738452385794); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316143403020, 1465587677695479810, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075786, 1465621050623209474, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075787, 1465621206781341698, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075788, 1465621319830417409, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075789, 1465621468124229634, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075790, 1465621601087860738, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075791, 1465621733564952578, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075792, 1465621843787067394, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075811, 1504776412970254338, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511894, 1504776412970254338, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075812, 1504779965155655682, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511895, 1504779965155655682, 1463431580473810945); +INSERT INTO `sys_role_menu_ref` VALUES (1505730836832075813, 1504780214448308226, 2); +INSERT INTO `sys_role_menu_ref` VALUES (1504780316210511896, 1504780214448308226, 1463431580473810945); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_tenant +-- ---------------------------- +DROP TABLE IF EXISTS `sys_tenant`; +CREATE TABLE `sys_tenant` ( + `id` bigint(19) NOT NULL COMMENT '唯一主键', + `tenant_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户名称', + `enable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用 0否 1是', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `role_code` (`tenant_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='角色信息表'; + +-- ---------------------------- +-- Records of sys_tenant +-- ---------------------------- +BEGIN; +INSERT INTO `sys_tenant` VALUES (1, '演示租户', '1', '演示租户', '0', 18, 1, '2017-03-08 15:00:42', 1465171199435362305, '2022-07-26 10:43:31', '2022-07-26 10:43:31'); +INSERT INTO `sys_tenant` VALUES (1315214795665907713, '测试租户', '0', '不启用租户', '0', 0, 1, '2020-10-11 16:56:57', 1, '2020-10-11 16:56:57', '2021-04-08 23:51:26'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `id` bigint(19) NOT NULL COMMENT '用户主键', + `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录账户', + `password` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录密码', + `password_level` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '登录密码强度', + `enable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '真实姓名', + `mobile` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机', + `no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '工号', + `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户头像', + `login_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后登陆IP', + `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱', + `sign` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '签名', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + `iz_exist_org` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否存在组织', + `iz_tenant_admin` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否租户管理员', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `enable_switch_tenant` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '允许切换租户(0 不允许 1 允许)', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '删除状态', + `version` int(11) NOT NULL COMMENT '版本(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` bigint(19) NOT NULL COMMENT '修改人', + `update_time` datetime NOT NULL COMMENT '修改时间', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE, + KEY `sys_user` (`username`,`real_name`) USING BTREE, + KEY `tenant` (`tenant_id`) USING BTREE COMMENT '租户' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户信息表'; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +BEGIN; +INSERT INTO `sys_user` VALUES (1, 'system', 'TS{MTY1OTM2NzA0MjMzOA==}$2a$10$FtVMZrf/LeM4ikU2ZXO8XuhmRDpJmIxLVm6Fa3ZEM8jVgZ2CFhuH6', '2', '1', '超级管理员', '15321010110', '112', 'http://upload.bedebug.com/20220802/1660928576913664278HC1G.jpg', '', 'meet.parker@foxmail.com', '没有自学能力的人没有未来', '', '0', '0', 0, '1', '0', 95, 1, '2020-09-25 15:03:22', 1, '2021-05-04 01:59:11', '2022-08-02 15:29:33'); +INSERT INTO `sys_user` VALUES (1313694379541635074, 'demo', 'TS{MTY1ODI5ODUzMzMwOA==}$2a$10$TS0LnHPhQT87rEpFi1A60.BeTQ80vCRGGL.5CPTqb61eCzP8HzueK', '2', '1', '租户内部管理员', '15311111111', 'test_001', 'http://upload.bedebug.com/20211013/1635589382475625280EW3N.jpg', '', 'meet.parker1@foxmail.com', NULL, NULL, '1', '0', 1, '0', '0', 6, 1, '2020-10-06 23:15:22', 1465879900211294210, '2021-12-01 16:42:13', '2022-07-27 13:49:16'); +INSERT INTO `sys_user` VALUES (1315218541317750785, 'zhangsan', 'TS{MTY1ODI5ODUzMzMwOA==}$2a$10$TS0LnHPhQT87rEpFi1A60.BeTQ80vCRGGL.5CPTqb61eCzP8HzueK', '2', '1', '张三', NULL, '123123', NULL, '', NULL, NULL, NULL, '1', '0', 1, '0', '0', 3, 1, '2020-10-11 17:11:50', 1, '2021-06-11 17:44:11', '2022-07-20 14:30:20'); +INSERT INTO `sys_user` VALUES (1315224823500120066, 'lyf', 'TS{MTY1ODI5ODUzMzMwOA==}$2a$10$TS0LnHPhQT87rEpFi1A60.BeTQ80vCRGGL.5CPTqb61eCzP8HzueK', '2', '1', '刘亦菲', NULL, '0101001', NULL, '', NULL, NULL, NULL, '1', '0', 1, '0', '0', 0, 1313694379541635074, '2020-10-11 17:36:48', 1313694379541635074, '2020-10-11 17:36:48', '2022-07-20 14:30:20'); +INSERT INTO `sys_user` VALUES (1465171199435362305, 'admin', 'TS{MTY1OTM2NDMzMzM5Nw==}$2a$10$2GTqJeztWRLOYDoB2EStm.FoncwpHG4GGtieD7qZbND1.cwjXx34u', '2', '1', '系统管理员', NULL, '01001', NULL, '', NULL, NULL, NULL, '1', '0', 0, '1', '0', 6, 1, '2021-11-29 12:10:10', 1, '2022-07-26 20:16:02', '2022-08-01 22:32:13'); +INSERT INTO `sys_user` VALUES (1465879900211294210, 'tenant', 'TS{MTY1ODI5ODUzMzMwOA==}$2a$10$TS0LnHPhQT87rEpFi1A60.BeTQ80vCRGGL.5CPTqb61eCzP8HzueK', '2', '1', '租户管理员', '15300000000', '123123', NULL, '', 'meet.parker2@foxmail.com', NULL, NULL, '0', '1', 1, '0', '0', 1, 1, '2021-12-01 11:06:17', 1, '2021-12-01 11:06:53', '2022-07-27 13:49:20'); +INSERT INTO `sys_user` VALUES (1465886867659096066, 'dept', 'TS{MTY1ODI5ODUzMzMwOA==}$2a$10$TS0LnHPhQT87rEpFi1A60.BeTQ80vCRGGL.5CPTqb61eCzP8HzueK', '2', '1', '部门管理员', NULL, '123213213', NULL, '', NULL, NULL, NULL, '1', '0', 1, '0', '0', 0, 1313694379541635074, '2021-12-01 11:33:59', 1313694379541635074, '2021-12-01 11:33:59', '2022-07-20 14:30:20'); +INSERT INTO `sys_user` VALUES (1465991640378986498, 'songyi', 'TS{MTY1ODI5ODUzMzMwOA==}$2a$10$TS0LnHPhQT87rEpFi1A60.BeTQ80vCRGGL.5CPTqb61eCzP8HzueK', '2', '1', '宋轶', NULL, '432431', NULL, '', NULL, NULL, NULL, '1', '0', 1, '0', '0', 0, 1465886867659096066, '2021-12-01 18:30:19', 1465886867659096066, '2021-12-01 18:30:19', '2022-07-20 14:30:20'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_user_org_ref +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_org_ref`; +CREATE TABLE `sys_user_org_ref` ( + `id` bigint(19) NOT NULL COMMENT '用户角色关联', + `user_id` bigint(19) NOT NULL COMMENT '用户主键', + `org_id` bigint(19) NOT NULL COMMENT '当前组织机构', + `org_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织机构组', + `iz_def` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否默认', + PRIMARY KEY (`id`) USING BTREE, + KEY `sys_org_user` (`user_id`,`org_ids`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='组织机构用户关联表'; + +-- ---------------------------- +-- Records of sys_user_org_ref +-- ---------------------------- +BEGIN; +INSERT INTO `sys_user_org_ref` VALUES (1403403014114373634, 1315218541317750785, 1332879851278856193, '0,1332710973848449026,1332879851278856193', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1448922152303259650, 1315224823500120066, 1448921834744115202, '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921834744115202', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1448925001863065602, 1448923198635307009, 1401861575953842177, '0,1401861234604605441,1401861575953842177', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1465587924685459458, 1465171199435362305, 1465586952575815681, '0,1465586952575815681', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1465886975591120898, 1465886867659096066, 1401861575953842177, '0,1401861234604605441,1401861575953842177', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1465964516926427137, 1313694379541635074, 1401861234604605441, '0,1401861234604605441', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1465964516926427138, 1313694379541635074, 1401873858511667201, '0,1401873858511667201', '0'); +INSERT INTO `sys_user_org_ref` VALUES (1465964516926427139, 1313694379541635074, 1332710973848449026, '0,1332710973848449026', '0'); +INSERT INTO `sys_user_org_ref` VALUES (1465988921358503938, 1465988919403958274, 1448921889865658369, '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921889865658369', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1465988921421418498, 1465988919403958274, 1448921889865658369, '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921889865658369', '0'); +INSERT INTO `sys_user_org_ref` VALUES (1465991642006376449, 1465991640378986498, 1448921889865658369, '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921889865658369', '1'); +INSERT INTO `sys_user_org_ref` VALUES (1465991642006376450, 1465991640378986498, 1448921889865658369, '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921889865658369', '0'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_user_role_ref +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_role_ref`; +CREATE TABLE `sys_user_role_ref` ( + `id` bigint(19) NOT NULL COMMENT '用户角色关联', + `user_id` bigint(19) NOT NULL COMMENT '用户主键', + `role_id` bigint(19) NOT NULL COMMENT '角色主键', + `iz_def` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否默认', + PRIMARY KEY (`id`) USING BTREE, + KEY `sys_user_role` (`user_id`,`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户角色关联表'; + +-- ---------------------------- +-- Records of sys_user_role_ref +-- ---------------------------- +BEGIN; +INSERT INTO `sys_user_role_ref` VALUES (1448927772578328577, 1315224823500120066, 1448924556381843458, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1448943254769410051, 1448923198635307009, 1448924556381843458, '0'); +INSERT INTO `sys_user_role_ref` VALUES (1448943254769410052, 1448923198635307009, 1448924616192618497, '0'); +INSERT INTO `sys_user_role_ref` VALUES (1448943254769410053, 1448923198635307009, 1448924680386441217, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1448943254769410054, 1448923198635307009, 1448924738452385794, '0'); +INSERT INTO `sys_user_role_ref` VALUES (1460635992343007233, 1460635865448534017, 2, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1465589100898349058, 1465171199435362305, 2, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1465882374703853570, 1465879900211294210, 1463431580473810945, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1465886929952899073, 1465886867659096066, 1448924680386441217, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1465964680936296449, 1313694379541635074, 1448924680386441217, '1'); +INSERT INTO `sys_user_role_ref` VALUES (1465997319281979394, 1465991640378986498, 1448924556381843458, '1'); +COMMIT; + +-- ---------------------------- +-- Table structure for test_car +-- ---------------------------- +DROP TABLE IF EXISTS `test_car`; +CREATE TABLE `test_car` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `car_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车名称', + `car_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车类型', + `car_brand` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '汽车品牌', + `produce_data` date NOT NULL COMMENT '生产日期', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + `org_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '组织机构组', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试汽车'; + +-- ---------------------------- +-- Records of test_car +-- ---------------------------- +BEGIN; +INSERT INTO `test_car` VALUES (1340634224709677058, '奔驰GXX', 'Gxx', '奔驰', '2020-12-20', '1', 1, '0', 0, 1313694379541635074, '2020-12-20 20:24:42', 1313694379541635074, '2020-12-20 20:24:42', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1340634337075081217, '北汽绅宝', '电动', '绅宝', '2020-12-13', '1', 1, '0', 0, 1313694379541635074, '2020-12-20 20:25:08', 1313694379541635074, '2020-12-20 20:25:08', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1340634432696823810, '宝马7系', '烧油', '宝马', '2020-12-20', '0', 1, '0', 0, 1313694379541635074, '2020-12-20 20:25:31', 1313694379541635074, '2020-12-20 20:25:31', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1340634485616357378, '测试', '123', '123', '2020-12-07', '0', 1, '1', 0, 1313694379541635074, '2020-12-20 20:25:44', 1313694379541635074, '2020-12-20 20:25:44', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1340635288087375874, '宝马7系', '烧油', '宝马', '2020-12-20', '0', 1, '0', 2, 1313694379541635074, '2020-12-20 20:28:55', 1313694379541635074, '2021-01-18 17:08:23', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1340635288095764482, '北汽绅宝', '电动', '绅宝', '2020-12-13', '1', 1, '0', 0, 1313694379541635074, '2020-12-20 20:28:55', 1313694379541635074, '2020-12-20 20:28:55', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1340635288099958786, '奔驰GXX', 'Gxx', '奔驰', '2020-12-20', '1', 1, '0', 0, 1313694379541635074, '2020-12-20 20:28:55', 1313694379541635074, '2020-12-20 20:28:55', '2021-04-08 23:51:39', ''); +INSERT INTO `test_car` VALUES (1448923884416593921, '演示汽车', '1111', '111', '2021-10-05', '1', 1, '1', 1, 1313694379541635074, '2021-10-15 16:09:08', 1, '2021-10-15 16:34:49', '2021-10-15 17:12:38', '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921834744115202'); +INSERT INTO `test_car` VALUES (1448927202366894081, '自己_范冰冰', '11111', '11111', '2021-10-04', '1', 1, '0', 1, 1448923198635307009, '2021-10-15 16:22:19', 1, '2021-10-15 16:34:37', '2021-10-15 16:32:54', '0,1401861234604605441,1401861575953842177'); +INSERT INTO `test_car` VALUES (1448927860478357506, '自己_刘亦菲', '111', '2222', '2021-10-04', '1', 1, '0', 1, 1315224823500120066, '2021-10-15 16:24:56', 1, '2021-10-15 16:34:28', '2021-10-15 16:32:45', '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921834744115202'); +INSERT INTO `test_car` VALUES (1448940392903516161, '自己_演示', '123123', '123123', '2021-10-04', '1', 1, '0', 1, 1313694379541635074, '2021-10-15 17:14:44', 1313694379541635074, '2021-11-30 18:05:11', '2021-11-30 18:02:56', '0,1401861234604605441,1401861575953842177'); +INSERT INTO `test_car` VALUES (1465997520956698625, '宋轶自己的车', '油车', '宝马', '2021-12-01', '1', 1, '0', 0, 1465991640378986498, '2021-12-01 18:53:41', 1465991640378986498, '2021-12-01 18:53:41', '2021-12-01 18:51:27', '0,1401861234604605441,1401861575953842177,1401873907685687297,1448921889865658369'); +INSERT INTO `test_car` VALUES (1465999901249384450, '测试汽车', '测试汽车', '测试汽车', '2021-12-01', '1', 1, '0', 0, 1465879900211294210, '2021-12-01 19:03:08', 1465879900211294210, '2021-12-01 19:03:08', '2021-12-01 19:00:54', NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for test_car_copy1 +-- ---------------------------- +DROP TABLE IF EXISTS `test_car_copy1`; +CREATE TABLE `test_car_copy1` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `car_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车名称', + `car_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车类型', + `car_brand` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '汽车品牌', + `produce_data` date NOT NULL COMMENT '生产日期', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试'; + +-- ---------------------------- +-- Table structure for test_car_copy2 +-- ---------------------------- +DROP TABLE IF EXISTS `test_car_copy2`; +CREATE TABLE `test_car_copy2` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `car_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车名称', + `car_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车类型', + `car_brand` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '汽车品牌', + `produce_data` date NOT NULL COMMENT '生产日期', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试'; + +-- ---------------------------- +-- Table structure for test_car_copy3 +-- ---------------------------- +DROP TABLE IF EXISTS `test_car_copy3`; +CREATE TABLE `test_car_copy3` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `car_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车名称', + `car_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车类型', + `car_brand` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '汽车品牌', + `produce_data` date NOT NULL COMMENT '生产日期', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试'; + +-- ---------------------------- +-- Table structure for test_car_copy4 +-- ---------------------------- +DROP TABLE IF EXISTS `test_car_copy4`; +CREATE TABLE `test_car_copy4` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `car_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车名称', + `car_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车类型', + `car_brand` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '汽车品牌', + `produce_data` date NOT NULL COMMENT '生产日期', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试'; + +-- ---------------------------- +-- Table structure for test_car_copy5 +-- ---------------------------- +DROP TABLE IF EXISTS `test_car_copy5`; +CREATE TABLE `test_car_copy5` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `car_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车名称', + `car_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '汽车类型', + `car_brand` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '汽车品牌', + `produce_data` date NOT NULL COMMENT '生产日期', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试'; + +-- ---------------------------- +-- Table structure for test_entity +-- ---------------------------- +DROP TABLE IF EXISTS `test_entity`; +CREATE TABLE `test_entity` ( + `id` bigint(19) NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `type` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `create_by` bigint(19) NOT NULL, + `create_time` datetime NOT NULL, + `update_by` bigint(19) NOT NULL, + `update_time` datetime NOT NULL, + `version` int(11) NOT NULL, + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ---------------------------- +-- Table structure for test_user +-- ---------------------------- +DROP TABLE IF EXISTS `test_user`; +CREATE TABLE `test_user` ( + `id` bigint(19) NOT NULL COMMENT '主键', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名称', + `money` double(8,2) NOT NULL COMMENT '金钱', + `age` smallint(5) NOT NULL COMMENT '年龄', + `birth` date NOT NULL COMMENT '生日', + `iz_usable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否启用', + `tenant_id` bigint(19) DEFAULT NULL COMMENT '多租户ID', + `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除标记:0未删除,1删除', + `version` int(10) NOT NULL COMMENT '版本号(乐观锁)', + `create_by` bigint(19) NOT NULL COMMENT '创建用户', + `create_time` datetime NOT NULL COMMENT '创建日期', + `update_by` bigint(19) NOT NULL COMMENT '修改用户', + `update_time` datetime NOT NULL COMMENT '修改日期', + `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='某系统用户'; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/docker-compose-server.yml b/docker-compose-server.yml index a01766d..704643c 100644 --- a/docker-compose-server.yml +++ b/docker-compose-server.yml @@ -2,7 +2,7 @@ version: '3.3' services: # 构建 MySQL数据库 这里不指定数据库文件 防止误操作 等隐患问题 opsli-boot-mysql: - build: ./db-file + build: ./db-file/2.0版本 image: opsli-boot-mysql restart: always environment: @@ -57,4 +57,4 @@ services: volumes: - /www/wwwroot/demo.opsli.bedebug.com/backend/run:/usr/local/opsli/opsli-boot #挂载目录 ports: - - "7000:7000" \ No newline at end of file + - "7000:7000" diff --git a/opsli-api/src/main/java/org/opsli/api/base/encrypt/BaseEncrypt.java b/opsli-api/src/main/java/org/opsli/api/base/encrypt/BaseEncrypt.java index b09119d..3995d8d 100644 --- a/opsli-api/src/main/java/org/opsli/api/base/encrypt/BaseEncrypt.java +++ b/opsli-api/src/main/java/org/opsli/api/base/encrypt/BaseEncrypt.java @@ -10,7 +10,7 @@ import java.io.Serializable; /** * 加解密 * - * @author 周鹏程 + * @author Parker * @date 2021-01-24 12:48 下午 **/ @Data diff --git a/opsli-api/src/main/java/org/opsli/api/base/encrypt/EncryptModel.java b/opsli-api/src/main/java/org/opsli/api/base/encrypt/EncryptModel.java new file mode 100644 index 0000000..03ad4f7 --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/base/encrypt/EncryptModel.java @@ -0,0 +1,42 @@ +/** + * 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.api.base.encrypt; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +import java.io.Serializable; + +/** + * 登陆 加解密 + * + * @author Parker + * @date 2021-01-24 12:48 下午 + **/ +@Data +public class EncryptModel implements Serializable { + + private static final long serialVersionUID = 1L; + + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(2000) + @ApiModelProperty(value = "加密数据") + private String encryptData; + +} diff --git a/opsli-api/src/main/java/org/opsli/api/base/result/ResultVo.java b/opsli-api/src/main/java/org/opsli/api/base/result/ResultVo.java deleted file mode 100644 index 118f64c..0000000 --- a/opsli-api/src/main/java/org/opsli/api/base/result/ResultVo.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.opsli.api.base.result; - -import com.alibaba.fastjson.JSONObject; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.http.HttpStatus; - -import java.io.Serializable; - -/** - * API 统一返回参数 - * 在 Feign 的调用过程中,无法直接序列化数据 - * 所以要加上 泛型对象 @JsonProperty ,否者返回则为一个null - * - * @date 2020年5月15日10:40:54 - * @author Parker - */ -@Data -@ApiModel(value="视图层返回Api对象", - description="视图层返回Api对象 success:成功状态 code:编号 msg:信息 timestamp:时间戳 data:数据") -public class ResultVo implements Serializable { - - private static final long serialVersionUID = 1L; - - /** 默认成功信息 */ - public static final String DEF_SUCCESS_MSG = "操作成功!"; - /** 默认失败信息 */ - public static final String DEF_ERROR_MSG = "操作失败!"; - - /** 成功状态 */ - @ApiModelProperty(value = "成功状态") - @JsonProperty("success") - private boolean success; - - /** 消息 */ - @ApiModelProperty(value = "消息") - @JsonProperty("msg") - private String msg; - - /** 状态码 */ - @ApiModelProperty(value = "状态码") - @JsonProperty("code") - private Integer code; - - /** 时间戳 */ - @ApiModelProperty(value = "时间戳") - @JsonProperty("timestamp") - private Long timestamp; - - /** 数据对象 */ - @ApiModelProperty(value = "数据") - @JsonProperty("data") - private T data; - - public T getData() { - return data; - } - - public ResultVo setData(T data) { - this.data = data; - return this; - } - - /** - * 转化成Json字符串 - * @return String - */ - public String toJsonStr(){ - return JSONObject.toJSONString(this); - } - - // =========================================== - - /** - * 构造函数 - */ - public ResultVo() { - // 初始化值 - this.success = true; - this.msg = DEF_SUCCESS_MSG; - this.code = HttpStatus.OK.value(); - this.timestamp = System.currentTimeMillis(); - } - - // ================================== 静态方法 =================================== - - /** - * 返回成功状态 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo success() { - return new ResultVo<>(); - } - - /** - * 返回成功状态 - * @param msg 返回信息 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo success(String msg) { - ResultVo ret = new ResultVo<>(); - ret.setMsg(msg); - return ret; - } - - /** - * 返回成功状态 - * @param data 返回数据 - * @param 泛型 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo success(T data) { - ResultVo ret = new ResultVo<>(); - ret.setData(data); - return ret; - } - - /** - * 返回成功状态 - * @param msg 返回信息 - * @param data 返回数据 - * @param 泛型 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo success(String msg, T data) { - ResultVo ret = new ResultVo<>(); - ret.setMsg(msg); - ret.setData(data); - return ret; - } - - /** - * 返回成功状态 - * @param msg 返回信息 - * @param data 返回数据 - * @param 泛型 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo success(Integer code, String msg, T data) { - ResultVo ret = new ResultVo<>(); - ret.setCode(code); - ret.setMsg(msg); - ret.setData(data); - return ret; - } - - - /** - * 返回错误状态 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo error() { - return ResultVo.error( - HttpStatus.INTERNAL_SERVER_ERROR.value() - , DEF_ERROR_MSG, null); - } - - /** - * 返回错误状态 - * @param msg 返回信息 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo error(String msg) { - return ResultVo.error( - HttpStatus.INTERNAL_SERVER_ERROR.value() - , msg, null); - } - - /** - * 返回错误状态 - * @param code 错误编号 - * @param msg 返回信息 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo error(Integer code, String msg) { - return ResultVo.error(code, msg, null); - } - - /** - * 返回成功状态 - * @param code 错误编号 - * @param data 返回数据 - * @param 泛型 - * @return ResultVo - */ - @JsonIgnore - public static ResultVo error(Integer code, String msg, T data) { - ResultVo ret = new ResultVo<>(); - ret.setMsg(msg); - ret.setCode(code); - ret.setData(data); - ret.setSuccess(false); - return ret; - } - -} diff --git a/opsli-api/src/main/java/org/opsli/api/base/result/ResultWrapper.java b/opsli-api/src/main/java/org/opsli/api/base/result/ResultWrapper.java new file mode 100644 index 0000000..704f7d7 --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/base/result/ResultWrapper.java @@ -0,0 +1,263 @@ +/** + * 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.api.base.result; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; +import lombok.experimental.Accessors; +import org.opsli.common.base.msg.BaseMsg; + +import java.io.Serializable; + +/** + * 返回包装类 + * + * @author Parker + * @date 2021年12月30日15:31:41 + */ +@Data +@Builder +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(value = "基础返回实体", + description="视图层返回Api对象 code:编号 msg:信息 timestamp:时间戳 data:数据") +public class ResultWrapper implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 响应提示信息 + */ + @ApiModelProperty(name = "msg", dataType = "string", value = "响应信息") + private String msg; + + /** + * 返回码:0正常,-1以上为错误信息 + */ + @ApiModelProperty(name = "code", dataType = "int", value = "响应码") + private int code; + + /** + * 返回 + */ + @ApiModelProperty(name = "data", dataType = "object", value = "数据内容") + private T data; + + /** + * 时间戳 + */ + @ApiModelProperty(name = "timestamp", dataType = "long", value = "时间戳") + private long timestamp; + + + + /** + * 获取默认的成功信息, + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getSuccessResultWrapperByMsg(String msg) { + return ResultWrapper.builder() + .code(StateCodeEnum.SUCCESS.getCode()) + .msg(msg) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取默认的成功信息, + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getSuccessResultWrapper() { + return getSuccessResultWrapper(null); + } + + + /** + * 获取默认的成功信息, + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param data 数据 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getSuccessResultWrapper(T data) { + return ResultWrapper.builder() + .code(StateCodeEnum.SUCCESS.getCode()) + .msg(StateCodeEnum.SUCCESS.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取默认的错误的信息 + * 默认的失败状态码 {@link StateCodeEnum#ERROR} + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getErrorResultWrapper() { + return getErrorResultWrapper(null); + } + + /** + * 获取默认的错误的信息 + * 默认的失败状态码 {@link StateCodeEnum#ERROR} + * @param data 数据 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getErrorResultWrapper(T data) { + return ResultWrapper.builder() + .code(StateCodeEnum.ERROR.getCode()) + .msg(StateCodeEnum.ERROR.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param stateCode 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getCustomResultWrapper(StateCodeEnum stateCode) { + return getCustomResultWrapper(null, stateCode); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param data 业务数据 + * @param stateCode 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getCustomResultWrapper(T data, StateCodeEnum stateCode) { + return ResultWrapper.builder() + .code(stateCode.getCode()) + .msg(stateCode.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param baseMsg 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getCustomResultWrapper(BaseMsg baseMsg) { + return getCustomResultWrapper(null, baseMsg); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param data 业务数据 + * @param baseMsg 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getCustomResultWrapper(T data, BaseMsg baseMsg) { + return ResultWrapper.builder() + .code(baseMsg.getCode()) + .msg(baseMsg.getMessage()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param data 业务数据 + * @param code 状态码 + * @param msg 提示信息 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getCustomResultWrapper(T data, int code, String msg) { + return ResultWrapper.builder() + .code(code) + .msg(msg) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param code 状态码 + * @param msg 提示信息 + * @param 泛型 + * @return ResultWrapper + */ + public static ResultWrapper getCustomResultWrapper(int code, String msg) { + return ResultWrapper.builder() + .code(code) + .msg(msg) + .data(null) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 验证返回结果是否成功, + * @param resultWrapper 返回包装类 + * @param 泛型 + * @return boolean + */ + public static boolean isSuccess(ResultWrapper resultWrapper) { + if(null == resultWrapper){ + return false; + } + + return StateCodeEnum.SUCCESS.getCode() == resultWrapper.getCode(); + } + + + /** + * 请求状态枚举 + * + * @author Parker + * @date 2021年12月30日15:29:29 + */ + @Getter + @AllArgsConstructor + public enum StateCodeEnum { + + /** 请求状态枚举 */ + + SUCCESS(0, "请求成功"), + + FAILURE(-1, "操作失败"), + + ERROR(-1, "服务器异常"); + + private final int code; + private final String msg; + } + +} diff --git a/opsli-api/src/main/java/org/opsli/api/web/gentest/carinfo/TestCarRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/gentest/carinfo/TestCarRestApi.java old mode 100644 new mode 100755 index 415108e..826e2af --- a/opsli-api/src/main/java/org/opsli/api/web/gentest/carinfo/TestCarRestApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/gentest/carinfo/TestCarRestApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.gentest.carinfo; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; @@ -25,7 +25,7 @@ import org.opsli.api.wrapper.gentest.carinfo.TestCarModel; /** - * 测试汽车 + * 测试汽车 Api * * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起 @@ -33,98 +33,97 @@ import org.opsli.api.wrapper.gentest.carinfo.TestCarModel; * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的 * * @author Parker - * @date 2020-12-20 20:12:57 + * @date 2022-08-06 23:53:30 */ public interface TestCarRestApi { /** 标题 */ - String TITLE = "汽车信息管理"; + String TITLE = "测试汽车"; /** 子标题 */ - String SUB_TITLE = "汽车信息"; + String SUB_TITLE = "测试汽车"; /** - * 汽车信息 查一条 + * 测试汽车 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(TestCarModel model); + ResultWrapper get(TestCarModel model); /** - * 汽车信息 查询分页 + * 测试汽车 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request ); /** - * 汽车信息 新增 + * 测试汽车 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody TestCarModel model); + ResultWrapper insert(@RequestBody TestCarModel model); /** - * 汽车信息 修改 + * 测试汽车 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody TestCarModel model); + ResultWrapper update(@RequestBody TestCarModel model); /** - * 汽车信息 删除 + * 测试汽车 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** - * 汽车信息 批量删除 + * 测试汽车 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** - * 汽车信息 Excel 导出 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + * 测试汽车 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); /** - * 汽车信息 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); + * 测试汽车 Excel 导出 + * + * @param certificate 凭证 + * @param response response + */ + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** - * 汽车信息 Excel 下载导入模版 - * @param response response + * 测试汽车 Excel 导入 + * @param request 文件流 request + * @return ResultWrapper */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + @PostMapping("/importExcel") + ResultWrapper importExcel(MultipartHttpServletRequest request); -} +} \ No newline at end of file diff --git a/opsli-api/src/main/java/org/opsli/api/web/gentest/user/TestUserRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/gentest/user/TestUserRestApi.java index ea859e6..634ca4b 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/gentest/user/TestUserRestApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/gentest/user/TestUserRestApi.java @@ -15,11 +15,8 @@ */ package org.opsli.api.web.gentest.user; -import org.opsli.api.base.result.ResultVo; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.opsli.api.base.result.ResultWrapper; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -48,20 +45,20 @@ public interface TestUserRestApi { /** * 某系统用户 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(TestUserModel model); + ResultWrapper get(TestUserModel model); /** * 某系统用户 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -70,56 +67,64 @@ public interface TestUserRestApi { /** * 某系统用户 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody TestUserModel model); + ResultWrapper insert(@RequestBody TestUserModel model); /** * 某系统用户 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody TestUserModel model); + ResultWrapper update(@RequestBody TestUserModel model); /** * 某系统用户 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 某系统用户 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** - * 某系统用户 Excel 导出 - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + * 某系统用户 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 某系统用户 Excel 导出 + * + * @param certificate 凭证 + * @param response response + */ + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 某系统用户 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); + ResultWrapper importExcel(MultipartHttpServletRequest request); - /** - * 某系统用户 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/area/SysAreaRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/area/SysAreaRestApi.java index 3bb4c38..7374738 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/area/SysAreaRestApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/area/SysAreaRestApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.area; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.area.SysAreaModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -48,80 +48,57 @@ public interface SysAreaRestApi { /** * 组织机构表 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(SysAreaModel model); + ResultWrapper get(SysAreaModel model); /** * 组织树 * @param parentId 父节点ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findTree") - ResultVo findTree(String parentId); + ResultWrapper findTree(String parentId); /** * 组织树 * @param deep 层级 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findTreeAll") - ResultVo findTreeAll(@RequestParam(name = "deep", defaultValue = "3", required = false) Integer deep); + ResultWrapper findTreeAll(@RequestParam(name = "deep", defaultValue = "3", required = false) Integer deep); /** * 组织机构表 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody SysAreaModel model); + ResultWrapper insert(@RequestBody SysAreaModel model); /** * 组织机构表 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody SysAreaModel model); + ResultWrapper update(@RequestBody SysAreaModel model); /** * 组织机构表 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 组织机构表 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); - - /** - * 组织机构表 Excel 导出 - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); - - /** - * 组织机构表 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 组织机构表 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper delAll(String ids); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictApi.java index 56ee5aa..e05fab6 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.dict; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.dict.DictModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -48,20 +48,20 @@ public interface DictApi { /** * 数据字典 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(DictModel model); + ResultWrapper get(DictModel model); /** * 数据字典 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -70,65 +70,42 @@ public interface DictApi { /** * 数据字典 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody DictModel model); + ResultWrapper insert(@RequestBody DictModel model); /** * 数据字典 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody DictModel model); + ResultWrapper update(@RequestBody DictModel model); /** * 数据字典 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 数据字典 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); - - /** - * 数据字典 Excel 导出 - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); - - /** - * 数据字典 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 数据字典 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper delAll(String ids); /** * 根据字典类型编号 查询出所有字典 * * @param typeCode 字典类型编号 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getDictListByCode") - ResultVo getDictListByCode(String typeCode); + ResultWrapper getDictListByCode(String typeCode); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictDetailApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictDetailApi.java index ca8c19a..26c871f 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictDetailApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/dict/DictDetailApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.dict; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.dict.DictDetailModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -49,20 +49,20 @@ public interface DictDetailApi { /** * 数据字典 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(DictDetailModel model); + ResultWrapper get(DictDetailModel model); /** * 数据字典 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -71,57 +71,34 @@ public interface DictDetailApi { /** * 数据字典 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody DictDetailModel model); + ResultWrapper insert(@RequestBody DictDetailModel model); /** * 数据字典 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody DictDetailModel model); + ResultWrapper update(@RequestBody DictDetailModel model); /** * 数据字典 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 数据字典 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); - - /** - * 数据字典 Excel 导出 - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); - - /** - * 数据字典 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 数据字典 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper delAll(String ids); // ================================ @@ -130,9 +107,9 @@ public interface DictDetailApi { * 根据字典类型编号 查询出所有字典 * * @param typeCode 字典类型编号 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findListByTypeCode") - ResultVo> findListByTypeCode(String typeCode); + ResultWrapper> findListByTypeCode(String typeCode); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/logs/LoginLogsApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/logs/LoginLogsApi.java index 767b623..f71a8de 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/logs/LoginLogsApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/logs/LoginLogsApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.logs; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.logs.LogsModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -48,10 +48,10 @@ public interface LoginLogsApi { * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/logs/LogsApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/logs/LogsApi.java index 86e82d7..0d5a7df 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/logs/LogsApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/logs/LogsApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.logs; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.logs.LogsModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -45,20 +45,20 @@ public interface LogsApi { /** * 日志 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(LogsModel model); + ResultWrapper get(LogsModel model); /** * 日志 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -68,8 +68,8 @@ public interface LogsApi { /** * 日志 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ - ResultVo insert(LogsModel model); + ResultWrapper insert(LogsModel model); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/logs/OperationLogRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/logs/OperationLogRestApi.java new file mode 100755 index 0000000..5df825a --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/web/system/logs/OperationLogRestApi.java @@ -0,0 +1,92 @@ +/** + * 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.api.web.system.logs; + +import org.opsli.api.base.result.ResultWrapper; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opsli.api.wrapper.system.logs.OperationLogModel; + + +/** + * 行为日志 Api + * + * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping + * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起 + * + * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的 + * + * @author Parker + * @date 2022-07-26 19:21:57 + */ +public interface OperationLogRestApi { + + /** 标题 */ + String TITLE = "行为日志"; + /** 子标题 */ + String SUB_TITLE = "行为日志"; + + /** + * 行为日志 查一条 + * @param model 模型 + * @return ResultWrapper + */ + @GetMapping("/get") + ResultWrapper get(OperationLogModel model); + + /** + * 行为日志 查询分页 + * @param pageNo 当前页 + * @param pageSize 每页条数 + * @param request request + * @return ResultWrapper + */ + @GetMapping("/findPage") + ResultWrapper findPage( + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest request + ); + + + + /** + * 行为日志 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 行为日志 Excel 导出 + * + * @param certificate 凭证 + * @param response response + */ + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); + + +} diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java index ded669d..bc3af3c 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/menu/MenuApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.menu; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.menu.MenuFullModel; import org.opsli.api.wrapper.system.menu.MenuModel; import org.springframework.web.bind.annotation.GetMapping; @@ -52,71 +52,71 @@ public interface MenuApi { * 获得列表菜单 * * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findMenuTreePage") - ResultVo findMenuTreePage(HttpServletRequest request); + ResultWrapper findMenuTreePage(HttpServletRequest request); /** * 懒加载列表菜单 * * @param parentId 父节点ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findMenuTreePageByLazy") - ResultVo findMenuTreePageByLazy(String parentId); + ResultWrapper findMenuTreePageByLazy(String parentId); /** * 懒加载菜单 * @param parentId 父节点ID * @param id 自身ID (不为空 则排除自身) - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findMenuTreeByLazy") - ResultVo findMenuTreeByLazy(String parentId, String id); + ResultWrapper findMenuTreeByLazy(String parentId, String id); /** * 获得当前用户登录菜单 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/findMenuTree") - ResultVo findMenuTree(); + ResultWrapper findMenuTree(); /** * 根据 获得用户 菜单 - 权限 * * @param label 标签 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getMenuAndPermsTree") - ResultVo getMenuAndPermsTree(String label); + ResultWrapper getMenuAndPermsTree(String label); /** * 获得集合 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findList") - ResultVo> findList(); + ResultWrapper> findList(); /** * 菜单 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(MenuModel model); + ResultWrapper get(MenuModel model); /** * 菜单 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -125,58 +125,34 @@ public interface MenuApi { /** * 菜单 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody MenuModel model); + ResultWrapper insert(@RequestBody MenuModel model); /** * 菜单 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody MenuModel model); + ResultWrapper update(@RequestBody MenuModel model); /** * 菜单 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 菜单 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); - - /** - * 菜单 Excel 导出 - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); - - /** - * 菜单 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 菜单 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); - + ResultWrapper delAll(String ids); // ================= 普通 @@ -184,14 +160,14 @@ public interface MenuApi { /** * 根据菜单权限 获得菜单 * @param permissions 菜单权限 - * @return ResultVo + * @return ResultWrapper */ - ResultVo getByPermissions(String permissions); + ResultWrapper getByPermissions(String permissions); /** * 菜单完整 新增 * @param menuFullModel 模型 - * @return ResultVo + * @return ResultWrapper */ - ResultVo saveMenuByFull(@RequestBody MenuFullModel menuFullModel); + ResultWrapper saveMenuByFull(@RequestBody MenuFullModel menuFullModel); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java index e3710b5..7cf56a7 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java @@ -17,11 +17,8 @@ package org.opsli.api.web.system.options; -import org.opsli.api.base.result.ResultVo; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.opsli.api.base.result.ResultWrapper; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -55,20 +52,20 @@ public interface OptionsApi { /** * 系统参数 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(OptionsModel model); + ResultWrapper get(OptionsModel model); /** * 系统参数 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -77,108 +74,105 @@ public interface OptionsApi { /** * 系统参数 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody OptionsModel model); + ResultWrapper insert(@RequestBody OptionsModel model); /** * 系统参数 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody OptionsModel model); + ResultWrapper update(@RequestBody OptionsModel model); /** * 系统参数 修改 * @param params Map - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/updateOptions") - ResultVo updateOptions(@RequestBody Map params); + ResultWrapper updateOptions(@RequestBody Map params); /** * 系统参数 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 系统参数 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** - * 系统参数 Excel 导出 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - * @return ResultVo - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + * 系统参数 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 系统参数 Excel 导出 + * + * @param certificate 凭证 + * @param response response + */ + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 系统参数 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 系统参数 Excel 下载导入模版 - * @param response response - * @return ResultVo - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper importExcel(MultipartHttpServletRequest request); // ========================== /** * 系统参数 查一条 * @param optionCode 参数编号 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getByCode") - ResultVo getByCode(String optionCode); + ResultWrapper getByCode(String optionCode); /** * 系统参数 查询全部 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findAllOptions") - ResultVo> findAllOptions(); + ResultWrapper> findAllOptions(); /** * 系统参数 查询全部 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findAll") - ResultVo> findAll(); + ResultWrapper> findAll(); /** * 系统参数 创建加密公私钥 * * @param type 类型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/createCrypto") - ResultVo createCrypto(String type); + ResultWrapper createCrypto(String type); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/org/SysOrgRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/org/SysOrgRestApi.java index 208f175..eae15b2 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/org/SysOrgRestApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/org/SysOrgRestApi.java @@ -15,11 +15,8 @@ */ package org.opsli.api.web.system.org; -import org.opsli.api.base.result.ResultVo; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.opsli.api.base.result.ResultWrapper; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -50,90 +47,67 @@ public interface SysOrgRestApi { * 获得懒加载树 * @param parentId 父级ID * @param id 忽略自身ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findTreeLazy") - ResultVo findTreeLazy(String parentId, String id); + ResultWrapper findTreeLazy(String parentId, String id); /** * 获得全量树 包含默认节点 * @param isGen 是否包含根节点 * @param id 忽略自身ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findTreeByDef") - ResultVo findTreeByDef(boolean isGen, String id); + ResultWrapper findTreeByDef(boolean isGen, String id); /** * 获得当前用户下 组织 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findTreeByDefWithUserToLike") - ResultVo findTreeByDefWithUserToLike(); + ResultWrapper findTreeByDefWithUserToLike(); // ================ /** * 组织机构表 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(SysOrgModel model); + ResultWrapper get(SysOrgModel model); /** * 组织机构表 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody SysOrgModel model); + ResultWrapper insert(@RequestBody SysOrgModel model); /** * 组织机构表 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody SysOrgModel model); + ResultWrapper update(@RequestBody SysOrgModel model); /** * 组织机构表 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 组织机构表 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); - - /** - * 组织机构表 Excel 导出 - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); - - /** - * 组织机构表 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 组织机构表 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper delAll(String ids); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleApi.java index 10a4311..094746a 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleApi.java @@ -15,12 +15,9 @@ */ package org.opsli.api.web.system.role; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.role.RoleModel; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; @@ -48,20 +45,20 @@ public interface RoleApi { /** * 角色 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(RoleModel model); + ResultWrapper get(RoleModel model); /** * 角色 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -70,56 +67,63 @@ public interface RoleApi { /** * 角色 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody RoleModel model); + ResultWrapper insert(@RequestBody RoleModel model); /** * 角色 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody RoleModel model); + ResultWrapper update(@RequestBody RoleModel model); /** * 角色 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 角色 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** - * 角色 Excel 导出 + * 角色 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 角色 Excel 导出 + * + * @param certificate 凭证 * @param response response */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 角色 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 角色 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper importExcel(MultipartHttpServletRequest request); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleMenuRefApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleMenuRefApi.java index a552fd1..922be08 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleMenuRefApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/role/RoleMenuRefApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.role; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.role.RoleMenuRefModel; import org.opsli.api.wrapper.system.role.RoleModel; import org.springframework.web.bind.annotation.GetMapping; @@ -49,18 +49,18 @@ public interface RoleMenuRefApi { /** * 获得当前已有权限 * @param model 角色Id - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getPerms") - ResultVo getPerms(RoleMenuRefModel model); + ResultWrapper getPerms(RoleMenuRefModel model); /** * 设置权限 * @param model roleId 角色Id * @param model permsIds 权限Id 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/setPerms") - ResultVo setPerms(@RequestBody RoleMenuRefModel model); + ResultWrapper setPerms(@RequestBody RoleMenuRefModel model); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/tenant/TenantApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/tenant/TenantApi.java index 8689798..34203c2 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/tenant/TenantApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/tenant/TenantApi.java @@ -15,12 +15,9 @@ */ package org.opsli.api.web.system.tenant; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.tenant.TenantModel; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; @@ -48,20 +45,20 @@ public interface TenantApi { /** * 租户 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(TenantModel model); + ResultWrapper get(TenantModel model); /** * 租户 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -70,57 +67,65 @@ public interface TenantApi { /** * 租户 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody TenantModel model); + ResultWrapper insert(@RequestBody TenantModel model); /** * 租户 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody TenantModel model); + ResultWrapper update(@RequestBody TenantModel model); /** * 租户 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 租户 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** - * 租户 Excel 导出 + * 租户 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 租户 Excel 导出 + * + * @param certificate 凭证 * @param response response */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 租户 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); + ResultWrapper importExcel(MultipartHttpServletRequest request); - /** - * 租户 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); /** @@ -128,18 +133,18 @@ public interface TenantApi { * * @param tenantId 租户ID * @param enable 状态 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/enableTenant") - ResultVo enableTenant(String tenantId, String enable); + ResultWrapper enableTenant(String tenantId, String enable); // ========================= /** * 获得已启用租户 查一条 * @param tenantId 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getTenantByUsable") - ResultVo getTenantByUsable(String tenantId); + ResultWrapper getTenantByUsable(String tenantId); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/user/UserApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/user/UserApi.java index 174ee50..35bc207 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/user/UserApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/user/UserApi.java @@ -15,14 +15,12 @@ */ package org.opsli.api.web.system.user; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.encrypt.EncryptModel; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.role.RoleModel; import org.opsli.api.wrapper.system.user.*; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; @@ -51,97 +49,123 @@ public interface UserApi { /** * 当前登陆用户信息 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getInfo") - ResultVo getInfo(HttpServletRequest request); + ResultWrapper getInfo(HttpServletRequest request); /** * 当前登陆用户信息 * * @param userId 用户ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getInfoById") - ResultVo getInfoById(String userId); + ResultWrapper getInfoById(String userId); /** * 当前登陆用户信息 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getOrg") - ResultVo getOrg(); + ResultWrapper getOrg(); /** * 当前登陆用户信息 * * @param userId 用户ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getOrgByUserId") - ResultVo getOrgByUserId(String userId); + ResultWrapper getOrgByUserId(String userId); /** * 根据 userId 获得用户角色Id集合 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getRoleIdsByUserId") - ResultVo> getRoleIdsByUserId(String userId); + ResultWrapper> getRoleIdsByUserId(String userId); + + /** + * 修改密码 ID + * + * @param encryptModel 账号密码 + * @return ResultVo + */ + @PostMapping("/updatePasswordById") + ResultWrapper updatePasswordById(@RequestBody EncryptModel encryptModel); /** * 修改密码 - * @param userPassword 账号密码 - * @return ResultVo + * @param encryptModel 账号密码 + * @return ResultWrapper */ @PostMapping("/updatePassword") - ResultVo updatePassword(@RequestBody UserPassword userPassword); + ResultWrapper updatePassword(@RequestBody EncryptModel encryptModel); /** - * 修改密码 ID - * - * @param userPassword 密码类 - * @return ResultVo + * 修改邮箱 + * @param encryptModel 加密数据 + * @return ResultWrapper */ - @PostMapping("/updatePasswordById") - ResultVo updatePasswordById(@RequestBody ToUserPassword userPassword); + @PostMapping("/updateEmail") + ResultWrapper updateEmail(@RequestBody EncryptModel encryptModel); + + /** + * 修改手机 + * @param encryptModel 加密数据 + * @return ResultWrapper + */ + @PostMapping("/updateMobile") + ResultWrapper updateMobile(@RequestBody EncryptModel encryptModel); + /** * 重置密码 ID * - * @param userId 用户ID - * @return ResultVo + * @param encryptModel 加密数据(用户ID) + * @return ResultWrapper */ @PostMapping("/resetPasswordById") - ResultVo resetPasswordById(String userId); + ResultWrapper resetPasswordById(@RequestBody EncryptModel encryptModel); /** * 变更账户状态 * - * @param userId 用户ID - * @param enable 启用状态 - * @return ResultVo + * @param encryptModel 加密数据(EnableUserModel) + * @return ResultWrapper */ @PostMapping("/enableAccount") - ResultVo enableAccount(String userId, String enable); + ResultWrapper enableAccount(@RequestBody EncryptModel encryptModel); + + /** + * 修改密码(忘记密码) + * + * @param encryptModel 加密数据 + * @return ResultWrapper + */ + @PostMapping("/updatePasswordByForget") + ResultWrapper updatePasswordByForget(@RequestBody EncryptModel encryptModel); + /** * 上传头像 * @param userAvatarModel 图片地址 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/updateAvatar") - ResultVo updateAvatar(@RequestBody UserAvatarModel userAvatarModel); + ResultWrapper updateAvatar(@RequestBody UserAvatarModel userAvatarModel); /** * 用户信息 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(UserModel model); + ResultWrapper get(UserModel model); /** * 用户信息 查询分页 @@ -149,10 +173,10 @@ public interface UserApi { * @param pageSize 每页条数 * @param orgIdGroup 组织ID组 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, @RequestParam(name = "orgIdGroup") String orgIdGroup, @@ -164,10 +188,10 @@ public interface UserApi { * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPageByTenant") - ResultVo findPageByTenant( + ResultWrapper findPageByTenant( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -178,91 +202,114 @@ public interface UserApi { /** * 用户信息 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody UserModel model); + ResultWrapper insert(@RequestBody UserModel model); /** * 用户信息 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody UserModel model); + ResultWrapper update(@RequestBody UserModel model); /** * 用户自身信息 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/updateSelf") - ResultVo updateSelf(@RequestBody UserModel model); + ResultWrapper updateSelf(@RequestBody UserModel model); /** * 用户信息 删除 - * @param id ID - * @return ResultVo + * @param encryptModel 加密(id ID) + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(@RequestBody EncryptModel encryptModel); /** * 用户信息 批量删除 - * @param ids ID 数组 - * @return ResultVo + * @param encryptModel 加密(ids ID 数组) + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(@RequestBody EncryptModel encryptModel); + /** - * 用户信息 Excel 导出 + * 用户信息 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 用户信息 Excel 导出 + * + * @param certificate 凭证 * @param response response */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 用户信息 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); + ResultWrapper importExcel(MultipartHttpServletRequest request); - /** - * 用户信息 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); /** * 切换租户 * @param tenantId 租户ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/switchTenant") - ResultVo switchTenant(String tenantId); + ResultWrapper switchTenant(String tenantId); /** * 切换回自己账户 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/switchOneself") - ResultVo switchOneself(); + ResultWrapper switchOneself(); /** * 根据 username 获得用户 * @param username 用户名 - * @return ResultVo + * @return ResultWrapper */ //@GetMapping("/getUserByUsername") - ResultVo getUserByUsername(String username); + ResultWrapper getUserByUsername(String username); + + /** + * 根据 手机号 获得用户 + * @param mobile 手机号 + * @return ResultWrapper + */ + ResultWrapper getUserByMobile(String mobile); + + /** + * 根据 邮箱 获得用户 + * @param email 邮箱 + * @return ResultWrapper + */ + ResultWrapper getUserByEmail(String email); diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/user/UserOrgRefApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/user/UserOrgRefApi.java index 97f24a0..05b2ccb 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/user/UserOrgRefApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/user/UserOrgRefApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.user; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.org.SysOrgModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefWebModel; @@ -47,25 +47,25 @@ public interface UserOrgRefApi { /** * 设置角色 * @param model 用户组织关联对象 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/setOrg") - ResultVo setOrg(@RequestBody UserOrgRefWebModel model); + ResultWrapper setOrg(@RequestBody UserOrgRefWebModel model); /** * 根据用户ID 获得组织列表 * @param userId 用户ID * @return List */ - ResultVo> findListByUserId(String userId); + ResultWrapper> findListByUserId(String userId); /** * 根据 userId 获得用户默认组织 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ //@GetMapping("/getRolesByUserId") - ResultVo getDefOrgByUserId(String userId); + ResultWrapper getDefOrgByUserId(String userId); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/user/UserRoleRefApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/user/UserRoleRefApi.java index 176314e..33a3d99 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/user/UserRoleRefApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/user/UserRoleRefApi.java @@ -15,7 +15,7 @@ */ package org.opsli.api.web.system.user; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.role.RoleMenuRefModel; import org.opsli.api.wrapper.system.role.RoleModel; @@ -48,50 +48,50 @@ public interface UserRoleRefApi { /** * 设置角色 * @param userId 用户ID - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getRoles") - ResultVo getRoles(String userId); + ResultWrapper getRoles(String userId); /** * 设置角色 * @param model 用户角色关联对象 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/setRoles") - ResultVo setRoles(@RequestBody UserRoleRefModel model); + ResultWrapper setRoles(@RequestBody UserRoleRefModel model); /** * 根据 userId 获得用户角色 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ //@GetMapping("/getRolesByUserId") - ResultVo> getRolesByUserId(String userId); + ResultWrapper> getRolesByUserId(String userId); /** * 根据 userId 获得用户默认角色 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ //@GetMapping("/getRolesByUserId") - ResultVo getDefRoleByUserId(String userId); + ResultWrapper getDefRoleByUserId(String userId); /** * 根据 userId 获得用户权限 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ //@GetMapping("/queryAllPerms") - ResultVo> getAllPerms(String userId); + ResultWrapper> getAllPerms(String userId); /** * 根据 userId 获得用户菜单 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ //@GetMapping("/queryAllPerms") - ResultVo> getMenuListByUserId(String userId); + ResultWrapper> getMenuListByUserId(String userId); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/test/TestApi.java b/opsli-api/src/main/java/org/opsli/api/web/test/TestApi.java index 3b24db6..31be2c5 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/test/TestApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/test/TestApi.java @@ -1,8 +1,9 @@ package org.opsli.api.web.test; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.test.TestModel; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -28,93 +29,93 @@ public interface TestApi { /** * 发送邮件 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/sendMail") - ResultVo sendMail(); + ResultWrapper sendMail(); /** * 发送 Redis 订阅消息 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/sendMsg") - ResultVo sendMsg(); + ResultWrapper sendMsg(); /** * 发送 Redis 订阅消息 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/redisTest") - ResultVo redisTest(); + ResultWrapper redisTest(); /** * 发起 Redis 分布式锁 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/testLock") - ResultVo testLock(); + ResultWrapper testLock(); /** * 新增数据 * @param entity entity - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/insert") - ResultVo insert(TestModel entity); + ResultWrapper insert(TestModel entity); /** * 修改数据 * @param entity entity - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/update") - ResultVo update(TestModel entity); + ResultWrapper update(TestModel entity); /** * 查看对象 * @param entity entity - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(TestModel entity); + ResultWrapper get(TestModel entity); /** * 删除对象 * @param id id - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 删除全部对象 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/delAll") - ResultVo delAll(); + ResultWrapper delAll(); /** * 查找一个集合 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findList") - ResultVo> findList(HttpServletRequest request); + ResultWrapper> findList(HttpServletRequest request); /** * 查找一个全部集合 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findAllList") - ResultVo> findAllList(); + ResultWrapper> findAllList(); /** @@ -123,10 +124,10 @@ public interface TestApi { * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -134,29 +135,36 @@ public interface TestApi { /** - * Excel 导出 + * Excel 导出认证 * + * @param type 类型 * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * Excel 导出 + * + * @param certificate 凭证 * @param response response */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * Excel 导入 * * @param request request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); + ResultWrapper importExcel(MultipartHttpServletRequest request); + - /** - * Excel 下载导入模版 - * - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); } diff --git a/opsli-api/src/main/java/org/opsli/api/web/test/TestRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/test/TestRestApi.java index c36e6c3..efaaa15 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/test/TestRestApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/test/TestRestApi.java @@ -15,12 +15,9 @@ */ package org.opsli.api.web.test; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.wrapper.test.TestModel; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; @@ -48,20 +45,20 @@ public interface TestRestApi { /** * 测试 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(TestModel model); + ResultWrapper get(TestModel model); /** * 测试 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -70,56 +67,65 @@ public interface TestRestApi { /** * 测试 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody TestModel model); + ResultWrapper insert(@RequestBody TestModel model); /** * 测试 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody TestModel model); + ResultWrapper update(@RequestBody TestModel model); /** * 测试 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 测试 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); + /** - * 测试 Excel 导出 + * 测试 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 测试 Excel 导出 + * + * @param certificate 凭证 * @param response response */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 测试 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); + ResultWrapper importExcel(MultipartHttpServletRequest request); - /** - * 测试 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); } diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/gentest/carinfo/TestCarModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/gentest/carinfo/TestCarModel.java old mode 100644 new mode 100755 index 03f73f9..4a16250 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/gentest/carinfo/TestCarModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/gentest/carinfo/TestCarModel.java @@ -15,6 +15,7 @@ */ package org.opsli.api.wrapper.gentest.carinfo; +import java.math.BigDecimal; import java.util.Date; import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.annotations.ApiModelProperty; @@ -23,17 +24,18 @@ import lombok.EqualsAndHashCode; import org.opsli.api.base.warpper.ApiWrapper; import org.opsli.common.annotation.validator.Validator; import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.annotation.validator.ValidatorLenMin; import org.opsli.common.enums.ValidatorType; import org.opsli.plugins.excel.annotation.ExcelInfo; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; /** - * 汽车信息 - * - * @author Parker - * @date 2020-12-20 20:12:57 - */ +* 测试汽车 Model +* +* @author Parker +* @date 2022-08-06 23:53:30 +*/ @Data @EqualsAndHashCode(callSuper = false) public class TestCarModel extends ApiWrapper { @@ -42,7 +44,10 @@ public class TestCarModel extends ApiWrapper { @ApiModelProperty(value = "汽车名称") @ExcelProperty(value = "汽车名称", order = 1) @ExcelInfo - @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL_WITH_CHINESE}) + @Validator({ + ValidatorType.IS_GENERAL_WITH_CHINESE, + ValidatorType.IS_NOT_NULL + }) @ValidatorLenMax(20) private String carName; @@ -50,7 +55,10 @@ public class TestCarModel extends ApiWrapper { @ApiModelProperty(value = "汽车类型") @ExcelProperty(value = "汽车类型", order = 2) @ExcelInfo - @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL_WITH_CHINESE}) + @Validator({ + ValidatorType.IS_GENERAL_WITH_CHINESE, + ValidatorType.IS_NOT_NULL + }) @ValidatorLenMax(20) private String carType; @@ -58,7 +66,9 @@ public class TestCarModel extends ApiWrapper { @ApiModelProperty(value = "汽车品牌") @ExcelProperty(value = "汽车品牌", order = 3) @ExcelInfo - @Validator({ValidatorType.IS_GENERAL_WITH_CHINESE}) + @Validator({ + ValidatorType.IS_GENERAL_WITH_CHINESE + }) @ValidatorLenMax(50) private String carBrand; @@ -66,6 +76,9 @@ public class TestCarModel extends ApiWrapper { @ApiModelProperty(value = "生产日期") @ExcelProperty(value = "生产日期", order = 4) @ExcelInfo + @Validator({ + ValidatorType.IS_NOT_NULL + }) @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private Date produceData; @@ -74,9 +87,12 @@ public class TestCarModel extends ApiWrapper { @ApiModelProperty(value = "是否启用") @ExcelProperty(value = "是否启用", order = 5) @ExcelInfo( dictType = "no_yes" ) + @Validator({ + ValidatorType.IS_NOT_NULL + }) @ValidatorLenMax(1) private String izUsable; -} +} \ No newline at end of file diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/LoginLogsModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/LoginLogsModel.java index 9e0c9d3..85352d1 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/LoginLogsModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/LoginLogsModel.java @@ -71,4 +71,10 @@ public class LoginLogsModel extends ApiWrapper { @ApiModelProperty(value = "用户代理") private String userAgent; + /** + * 登陆来源 + */ + @ApiModelProperty(value = "登陆来源") + private String loginFrom; + } diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/OperationLogModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/OperationLogModel.java new file mode 100755 index 0000000..cd8eb1c --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/logs/OperationLogModel.java @@ -0,0 +1,132 @@ +/** + * 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.api.wrapper.system.logs; + +import java.math.BigDecimal; +import java.util.Date; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.opsli.api.base.warpper.ApiWrapper; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.annotation.validator.ValidatorLenMin; +import org.opsli.common.enums.ValidatorType; +import org.opsli.plugins.excel.annotation.ExcelInfo; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +/** +* 行为日志 Model +* +* @author Parker +* @date 2022-07-26 19:21:57 +*/ +@Data +@EqualsAndHashCode(callSuper = false) +public class OperationLogModel extends ApiWrapper { + + /** 多租户字段 */ + private String tenantId; + + /** 日志等级 */ + @ApiModelProperty(value = "日志等级") + @ExcelProperty(value = "日志等级", order = 1) + @ExcelInfo( dictType = "log_level" ) + @ValidatorLenMax(8) + private String level; + + /** 被操作的系统模块 */ + @ApiModelProperty(value = "被操作的系统模块") + @ExcelProperty(value = "被操作的系统模块", order = 2) + @ExcelInfo( dictType = "log_model_type" ) + @ValidatorLenMax(20) + private String moduleId; + + /** 方法名 */ + @ApiModelProperty(value = "方法名") + @ExcelProperty(value = "方法名", order = 3) + @ExcelInfo + @ValidatorLenMax(100) + private String method; + + /** 参数 */ + @ApiModelProperty(value = "参数") + @ExcelProperty(value = "参数", order = 4) + @ExcelInfo + @ValidatorLenMax(20000) + private String args; + + /** 操作人id */ + @ApiModelProperty(value = "操作人id") + @ExcelProperty(value = "操作人id", order = 5) + @ExcelInfo + @ValidatorLenMax(19) + private String userId; + + /** 操作账号 */ + @ApiModelProperty(value = "操作账号") + @ExcelProperty(value = "操作账号", order = 6) + @ExcelInfo + @ValidatorLenMax(32) + private String username; + + /** 操作人真实名称 */ + @ApiModelProperty(value = "操作人真实名称") + @ExcelProperty(value = "操作人真实名称", order = 7) + @ExcelInfo + @ValidatorLenMax(50) + private String realName; + + /** 日志描述 */ + @ApiModelProperty(value = "日志描述") + @ExcelProperty(value = "日志描述", order = 8) + @ExcelInfo + @ValidatorLenMax(255) + private String description; + + /** 操作类型 */ + @ApiModelProperty(value = "操作类型") + @ExcelProperty(value = "操作类型", order = 9) + @ExcelInfo( dictType = "log_operation_type" ) + @ValidatorLenMax(20) + private String operationType; + + /** 方法运行时间 */ + @ApiModelProperty(value = "方法运行时间") + @ExcelProperty(value = "方法运行时间", order = 10) + @ExcelInfo + @ValidatorLenMax(19) + private String runTime; + + /** 方法返回值 */ + @ApiModelProperty(value = "方法返回值") + @ExcelProperty(value = "方法返回值", order = 11) + @ExcelInfo + @ValidatorLenMax(20000) + private String returnValue; + + /** 日志请求类型 */ + @ApiModelProperty(value = "日志请求类型") + @ExcelProperty(value = "日志请求类型", order = 12) + @ExcelInfo( dictType = "log_type" ) + @ValidatorLenMax(8) + private String logType; + + + +} diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/EnableUserModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/EnableUserModel.java new file mode 100644 index 0000000..52dd5a2 --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/EnableUserModel.java @@ -0,0 +1,42 @@ +/** + * 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.api.wrapper.system.user; + +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +/** + * 启用用户 + * + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Data +public class EnableUserModel { + + /** 主键 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(50) + private String userId; + + /** 是否启用 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(10) + private String enabled; + +} diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/ToUserPassword.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/ToUserPassword.java index 6230203..f79ff92 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/ToUserPassword.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/ToUserPassword.java @@ -51,12 +51,6 @@ public class ToUserPassword implements Serializable { @ValidatorLenMax(50) private String newPassword; - /** 盐值,密码秘钥 前端不可改*/ - @ApiModelProperty(value = "盐值,密码秘钥 前端不可改") - @ExcelIgnore - @ValidatorLenMax(50) - private String salt; - /** 登录密码强度 前端不可改 */ @ApiModelProperty(value = "登录密码强度 前端不可改") @ExcelIgnore diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserEmailModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserEmailModel.java new file mode 100644 index 0000000..ecac9b9 --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserEmailModel.java @@ -0,0 +1,46 @@ +/** + * 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.api.wrapper.system.user; + +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +/** + * 修改用户邮箱 + * + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Data +public class UpdateUserEmailModel { + + /** 主键 */ + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_EMAIL}) + @ValidatorLenMax(50) + private String email; + + /** 验证码 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(20) + private String verificationCode; + + /** 凭证 */ + @Validator({ValidatorType.IS_NOT_NULL}) + private String certificate; + +} diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserMobileModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserMobileModel.java new file mode 100644 index 0000000..f8e990a --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserMobileModel.java @@ -0,0 +1,46 @@ +/** + * 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.api.wrapper.system.user; + +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +/** + * 修改用户手机 + * + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Data +public class UpdateUserMobileModel { + + /** 主键 */ + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_MOBILE}) + @ValidatorLenMax(50) + private String mobile; + + /** 验证码 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(20) + private String verificationCode; + + /** 凭证 */ + @Validator({ValidatorType.IS_NOT_NULL}) + private String certificate; + +} diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserPasswordByForgetModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserPasswordByForgetModel.java new file mode 100644 index 0000000..c5fba3a --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UpdateUserPasswordByForgetModel.java @@ -0,0 +1,53 @@ +/** + * 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.api.wrapper.system.user; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.annotation.validator.ValidatorLenMin; +import org.opsli.common.enums.ValidatorType; + +import java.io.Serializable; + +/** + * 用户 修改密码 + * + * @author Parker + * @date 2020-09-16 17:33 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ExcelIgnoreUnannotated +public class UpdateUserPasswordByForgetModel implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 新密码 */ + @ApiModelProperty(value = "新密码") + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_SECURITY_PASSWORD}) + @ValidatorLenMin(6) + @ValidatorLenMax(50) + private String newPassword; + + /** 凭证 */ + @Validator({ValidatorType.IS_NOT_NULL}) + private String certificate; + +} diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java index eef19d3..0e00c8e 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserInfo.java @@ -56,12 +56,12 @@ public class UserInfo extends ApiWrapper { /** 手机 */ @ApiModelProperty(value = "手机") - @Validator({ValidatorType.IS_MOBILE}) + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_MOBILE}) private String mobile; /** 邮箱 */ @ApiModelProperty(value = "邮箱") - @Validator({ValidatorType.IS_EMAIL}) + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_EMAIL}) private String email; /** 工号 */ diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java index 31774ef..b4e83e7 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserModel.java @@ -60,12 +60,6 @@ public class UserModel extends ApiWrapper { @ValidatorLenMax(1) private String passwordLevel; - /** 盐值,密码秘钥 */ - @ApiModelProperty(value = "盐值,密码秘钥") - @ExcelIgnore - @ValidatorLenMax(50) - private String secretKey; - /** 是否启用 */ @ApiModelProperty(value = "是否启用") @ExcelIgnore @@ -84,14 +78,14 @@ public class UserModel extends ApiWrapper { @ApiModelProperty(value = "手机") @ExcelProperty(value = "手机", order = 2) @ExcelInfo - @Validator({ValidatorType.IS_MOBILE}) + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_MOBILE}) private String mobile; /** 邮箱 */ @ApiModelProperty(value = "邮箱") @ExcelProperty(value = "邮箱", order = 3) @ExcelInfo - @Validator({ValidatorType.IS_EMAIL}) + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_EMAIL}) @ValidatorLenMax(100) private String email; diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserPassword.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserPassword.java index c685c0c..467a19e 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserPassword.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserPassword.java @@ -58,12 +58,6 @@ public class UserPassword implements Serializable { @ValidatorLenMax(50) private String newPassword; - /** 盐值,密码秘钥 前端不可改*/ - @ApiModelProperty(value = "盐值,密码秘钥 前端不可改") - @ExcelIgnore - @ValidatorLenMax(50) - private String salt; - /** 登录密码强度 前端不可改 */ @ApiModelProperty(value = "登录密码强度 前端不可改") @ExcelIgnore diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserWebModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserWebModel.java index 531f168..a6f569a 100644 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserWebModel.java +++ b/opsli-api/src/main/java/org/opsli/api/wrapper/system/user/UserWebModel.java @@ -64,12 +64,6 @@ public class UserWebModel extends ApiWrapper { @ValidatorLenMax(1) private String passwordLevel; - /** 盐值,密码秘钥 */ - @ApiModelProperty(value = "盐值,密码秘钥") - @ExcelIgnore - @ValidatorLenMax(50) - private String secretKey; - /** 启用状态 */ @ApiModelProperty(value = "启用状态") @ExcelIgnore diff --git a/opsli-base-support/opsli-common/pom.xml b/opsli-base-support/opsli-common/pom.xml index 1ee087a..d90beb3 100644 --- a/opsli-base-support/opsli-common/pom.xml +++ b/opsli-base-support/opsli-common/pom.xml @@ -22,4 +22,4 @@ - \ No newline at end of file + diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/api/ResultVoMap.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/api/ResultVoMap.java index 8ca946c..4b9e6c0 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/api/ResultVoMap.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/api/ResultVoMap.java @@ -70,13 +70,20 @@ public class ResultVoMap extends HashMap implements Serializable // ------------------------------------------- - @JsonIgnore//返回对象时忽略此属性 + /** + * 返回对象时忽略此属性 + */ + @JsonIgnore public static ResultVoMap success(String msg) { ResultVoMap j = new ResultVoMap(); j.setMsg(msg); return j; } - @JsonIgnore//返回对象时忽略此属性 + + /** + * 返回对象时忽略此属性 + */ + @JsonIgnore// public static ResultVoMap error(String msg) { ResultVoMap j = new ResultVoMap(); j.setSuccess(false); @@ -84,14 +91,20 @@ public class ResultVoMap extends HashMap implements Serializable return j; } - @JsonIgnore//返回对象时忽略此属性 + /** + * 返回对象时忽略此属性 + */ + @JsonIgnore public static ResultVoMap success(Map map) { ResultVoMap restResponse = new ResultVoMap(); restResponse.putAll(map); return restResponse; } - @JsonIgnore//返回对象时忽略此属性 + /** + * 返回对象时忽略此属性 + */ + @JsonIgnore public static ResultVoMap success() { return new ResultVoMap(); } 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 index c12aef2..f0aed60 100644 --- 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 @@ -3,7 +3,7 @@ package org.opsli.common.constants; /** * Redis 常量 * {} 为项目名称 - * @author 周鹏程 + * @author Parker * @date 2021/12/10 19:52 */ public final class RedisConstants { @@ -47,9 +47,12 @@ public final class RedisConstants { /** 用户ID 和 菜单 */ public static final String PREFIX_USER_ID_MENUS = "kv#{}:user_id:menus:"; - /** 用户名 */ - public static final String PREFIX_USERNAME = "kv#{}:username:"; - + /** 用户名 + 用户ID */ + public static final String PREFIX_USER_USERNAME = "kv#{}:user:username_id:"; + /** 手机号 + 用户ID */ + public static final String PREFIX_USER_MOBILE = "kv#{}:user:mobile_id:"; + /** 邮箱 + 用户ID */ + public static final String PREFIX_USER_EMAIL = "kv#{}:user:email_id:"; /** 票据 */ @@ -61,8 +64,21 @@ public final class RedisConstants { /** 账号失败锁定KEY */ public static final String PREFIX_ACCOUNT_SLIP_LOCK = "kv#{}:account:slip:lock:"; + /** 临时邮箱验证码 */ + public static final String PREFIX_TMP_EMAIL_CODE_NAME = "kv#{}:verification:email:code:"; + + /** 临时手机验证码 */ + public static final String PREFIX_TMP_MOBILE_CODE_NAME = "kv#{}:verification:mobile:code:"; + /** 验证码凭证 用于验证码二次校验(唯一流水号 increment) */ + public static final String PREFIX_TMP_VERIFICATION_CERTIFICATE_NUM_NAME = "kv#{}:verification:certificate-num"; + /** 验证码凭证 用于验证码二次校验 */ + public static final String PREFIX_TMP_VERIFICATION_CERTIFICATE_NAME = "kv#{}:verification:certificate:"; + /** Excel 导出(唯一流水号 increment) */ + public static final String PREFIX_TMP_EXCEL_EXPORT_NUM_NAME = "kv#{}:excel-export-num"; + /** Excel 导出 凭证 */ + public static final String PREFIX_TMP_EXCEL_EXPORT_NAME = "kv#{}:excel-export:"; 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 7719888..eafb22c 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 @@ -17,6 +17,9 @@ public final class SignConstants { /** 租户ID */ public static final String TENANT_ID = "tenantId"; + /** 登陆来源 */ + public static final String LOGIN_FROM = "loginFrom"; + /** 时间戳 */ public static final String TIMESTAMP = "timestamp"; diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java index a93c022..7186ae0 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/DictType.java @@ -19,7 +19,7 @@ package org.opsli.common.enums; /** * 字典类型 * - * @author : 周鹏程 + * @author : Parker * @date : 2020-09-17 23:40 */ public enum DictType { diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/LoginFromEnum.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/LoginFromEnum.java new file mode 100644 index 0000000..2f1c177 --- /dev/null +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/LoginFromEnum.java @@ -0,0 +1,77 @@ +/** + * 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.enums; + + +import cn.hutool.core.bean.BeanUtil; + +import java.util.Arrays; + +/** + * 登录类型 + * + * @author 周鹏程 + * @date 2020-09-17 23:40 + */ +public enum LoginFromEnum { + + /** 账号 */ + PC("0"), + /** APP - 安卓 */ + APP_ANDROID("1"), + /** APP - 苹果 */ + APP_IOS("2"), + /** 微信小程序 */ + WX_APPLET("3"), + /** h5 */ + H5("4"), + /** 未知 */ + UNKNOWN("-1"), + + ; + + private final static String FILED_NAME = "loginFrom"; + /***/ + private final String type; + + LoginFromEnum(String type){ + this.type = type; + } + + public String getType() { + return this.type; + } + + public static LoginFromEnum getByCode(String code){ + return Arrays.stream(LoginFromEnum.values()) + .filter(value -> value.getType().equals(code)) + .findFirst().orElse(LoginFromEnum.UNKNOWN); + } + + public static LoginFromEnum getByBean(Object bean){ + if(null == bean || !BeanUtil.isBean(bean.getClass())){ + return LoginFromEnum.UNKNOWN; + } + + Object fieldValue = BeanUtil.getFieldValue(bean, FILED_NAME); + if(null == fieldValue){ + return LoginFromEnum.UNKNOWN; + } + + return getByCode((String) fieldValue); + } + +} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/LoginModelType.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/LoginModelType.java new file mode 100644 index 0000000..00708b6 --- /dev/null +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/LoginModelType.java @@ -0,0 +1,61 @@ +/** + * 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.enums; + +import cn.hutool.core.lang.Validator; +import cn.hutool.core.util.StrUtil; + +/** + * 登陆类型 + * + * @author Parker + * @date 2022-07-21 2:07 PM + **/ +public enum LoginModelType { + + /** 未知 */ + UNKNOWN, + + /** 账号 */ + ACCOUNT, + + /** 手机 */ + MOBILE, + + /** 邮箱 */ + EMAIL + + ; + + public static LoginModelType getTypeByStr(String principal){ + if(StrUtil.isBlank(principal)){ + return UNKNOWN; + } + + // 手机号 + if(Validator.isMobile(principal)){ + return MOBILE; + } + // 邮箱 + else if(Validator.isEmail(principal)){ + return EMAIL; + } + + // 默认账号 + return ACCOUNT; + } + +} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/VerificationTypeEnum.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/VerificationTypeEnum.java new file mode 100644 index 0000000..b78b398 --- /dev/null +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/enums/VerificationTypeEnum.java @@ -0,0 +1,53 @@ +/** + * 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.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; + +/** + * 验证类型 + * + * @author 周鹏程 + * @date 2022-08-01 12:49 PM + **/ +@AllArgsConstructor +@Getter +public enum VerificationTypeEnum { + + /** 类型 */ + LOGIN("0"), + + AUTH("1") + + ; + + /** 类型 */ + private final String type; + + public static Optional getEnumByType(String type){ + VerificationTypeEnum[] types = values(); + for (VerificationTypeEnum typeEnum : types) { + if(typeEnum.type.equals(type)){ + return Optional.of(typeEnum); + } + } + return Optional.empty(); + } + +} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorByWait.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorByWait.java index 738e6c6..0676a56 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorByWait.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorByWait.java @@ -32,7 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger; * 用于当前方法中复杂业务多线程处理,等待线程执行完毕后 获得统一结果 * 2021年11月2日14:07:54 重构 多线程异步等待执行器 * - * @author 周鹏程 + * @author Parker * @date 2020-12-10 10:36 */ @Slf4j diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorOldByWait.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorOldByWait.java index 61fdd1e..71ae43e 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorOldByWait.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessExecutorOldByWait.java @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger; * 多线程锁执行器 * 用于当前方法中复杂业务多线程处理,等待线程执行完毕后 获得统一结果 * - * @author 周鹏程 + * @author Parker * @date 2020-12-10 10:36 */ @Slf4j diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessor.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessor.java index c6ccaa7..cd20214 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessor.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/AsyncProcessor.java @@ -1,3 +1,18 @@ +/** + * 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.thread; import cn.hutool.core.util.StrUtil; @@ -14,7 +29,7 @@ import java.util.function.Function; /** * 自定义线程执行器 - 等待线程执行完毕不拒绝 * - * @author 周鹏程 + * @author Parker * @date 2020-10-08 10:24 */ @Slf4j diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/SyncProcessSingleExecutor.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/SyncProcessSingleExecutor.java index dadda2a..71f0c4d 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/SyncProcessSingleExecutor.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/thread/SyncProcessSingleExecutor.java @@ -1,3 +1,18 @@ +/** + * 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.thread; import cn.hutool.core.thread.ThreadUtil; @@ -11,7 +26,7 @@ import java.util.concurrent.ExecutorService; /** * 单线程池 * - * @author 周鹏程 + * @author Parker * @date 2021/8/27 17:00 */ @Slf4j diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/HashIdsUtil.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/HashIdsUtil.java new file mode 100644 index 0000000..7323a3a --- /dev/null +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/HashIdsUtil.java @@ -0,0 +1,388 @@ +package org.opsli.common.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Hashids designed for Generating short hashes from numbers (like YouTube and Bitly), obfuscate + * database IDs, use them as forgotten password hashes, invitation codes, store shard numbers. + *

+ * This is implementation of http://hashids.org v1.0.0 version. + * + * This implementation is immutable, thread-safe, no lock is necessary. + * + * @author fanweixiao + * @author Tercio Gaudencio Filho + * @since 0.3.3 + */ +public class HashIdsUtil { + /** + * Max number that can be encoded with Hashids. + */ + public static final long MAX_NUMBER = 9007199254740992L; + + private static final String DEFAULT_ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + private static final String DEFAULT_SEPS = "cfhistuCFHISTU"; + private static final String DEFAULT_SALT = ""; + + private static final int DEFAULT_MIN_HASH_LENGTH = 0; + private static final int MIN_ALPHABET_LENGTH = 16; + private static final double SEP_DIV = 3.5; + private static final int GUARD_DIV = 12; + + private final String salt; + private final int minHashLength; + private final String alphabet; + private final String seps; + private final String guards; + + public HashIdsUtil() { + this(DEFAULT_SALT); + } + + public HashIdsUtil(String salt) { + this(salt, 0); + } + + public HashIdsUtil(String salt, int minHashLength) { + this(salt, minHashLength, DEFAULT_ALPHABET); + } + + public HashIdsUtil(String salt, int minHashLength, String alphabet) { + this.salt = salt != null ? salt : DEFAULT_SALT; + this.minHashLength = minHashLength > 0 ? minHashLength : DEFAULT_MIN_HASH_LENGTH; + + final StringBuilder uniqueAlphabet = new StringBuilder(); + for (int i = 0; i < alphabet.length(); i++) { + if (uniqueAlphabet.indexOf(String.valueOf(alphabet.charAt(i))) == -1) { + uniqueAlphabet.append(alphabet.charAt(i)); + } + } + + alphabet = uniqueAlphabet.toString(); + + if (alphabet.length() < MIN_ALPHABET_LENGTH) { + throw new IllegalArgumentException( + "alphabet must contain at least " + MIN_ALPHABET_LENGTH + " unique characters"); + } + + if (alphabet.contains(" ")) { + throw new IllegalArgumentException("alphabet cannot contains spaces"); + } + + // seps should contain only characters present in alphabet; + // alphabet should not contains seps + String seps = DEFAULT_SEPS; + for (int i = 0; i < seps.length(); i++) { + final int j = alphabet.indexOf(seps.charAt(i)); + if (j == -1) { + seps = seps.substring(0, i) + " " + seps.substring(i + 1); + } else { + alphabet = alphabet.substring(0, j) + " " + alphabet.substring(j + 1); + } + } + + alphabet = alphabet.replaceAll("\\s+", ""); + seps = seps.replaceAll("\\s+", ""); + seps = HashIdsUtil.consistentShuffle(seps, this.salt); + + if ((seps.isEmpty()) || (((float) alphabet.length() / seps.length()) > SEP_DIV)) { + int seps_len = (int) Math.ceil(alphabet.length() / SEP_DIV); + + if (seps_len == 1) { + seps_len++; + } + + if (seps_len > seps.length()) { + final int diff = seps_len - seps.length(); + seps += alphabet.substring(0, diff); + alphabet = alphabet.substring(diff); + } else { + seps = seps.substring(0, seps_len); + } + } + + alphabet = HashIdsUtil.consistentShuffle(alphabet, this.salt); + // use double to round up + final int guardCount = (int) Math.ceil((double) alphabet.length() / GUARD_DIV); + + String guards; + if (alphabet.length() < 3) { + guards = seps.substring(0, guardCount); + seps = seps.substring(guardCount); + } else { + guards = alphabet.substring(0, guardCount); + alphabet = alphabet.substring(guardCount); + } + this.guards = guards; + this.alphabet = alphabet; + this.seps = seps; + } + + /** + * Encrypt numbers to string + * + * @param numbers + * the numbers to encrypt + * @return the encrypt string + */ + public String encode(long... numbers) { + if (numbers.length == 0) { + return ""; + } + + for (final long number : numbers) { + if (number < 0) { + return ""; + } + if (number > MAX_NUMBER) { + throw new IllegalArgumentException("number can not be greater than " + MAX_NUMBER + "L"); + } + } + return this._encode(numbers); + } + + /** + * Decrypt string to numbers + * + * @param hash + * the encrypt string + * @return decryped numbers + */ + public long[] decode(String hash) { + if (hash.isEmpty()) { + return new long[0]; + } + + String validChars = this.alphabet + this.guards + this.seps; + for (int i = 0; i < hash.length(); i++) { + if(validChars.indexOf(hash.charAt(i)) == -1) { + return new long[0]; + } + } + + return this._decode(hash, this.alphabet); + } + + /** + * Encrypt hexa to string + * + * @param hexa + * the hexa to encrypt + * @return the encrypt string + */ + public String encodeHex(String hexa) { + if (!hexa.matches("^[0-9a-fA-F]+$")) { + return ""; + } + + final List matched = new ArrayList(); + final Matcher matcher = Pattern.compile("[\\w\\W]{1,12}").matcher(hexa); + + while (matcher.find()) { + matched.add(Long.parseLong("1" + matcher.group(), 16)); + } + + // conversion + final long[] result = new long[matched.size()]; + for (int i = 0; i < matched.size(); i++) { + result[i] = matched.get(i); + } + + return this.encode(result); + } + + /** + * Decrypt string to numbers + * + * @param hash + * the encrypt string + * @return decryped numbers + */ + public String decodeHex(String hash) { + final StringBuilder result = new StringBuilder(); + final long[] numbers = this.decode(hash); + + for (final long number : numbers) { + result.append(Long.toHexString(number).substring(1)); + } + + return result.toString(); + } + + public static int checkedCast(long value) { + final int result = (int) value; + if (result != value) { + // don't use checkArgument here, to avoid boxing + throw new IllegalArgumentException("Out of range: " + value); + } + return result; + } + + /* Private methods */ + + private String _encode(long... numbers) { + long numberHashInt = 0; + for (int i = 0; i < numbers.length; i++) { + numberHashInt += (numbers[i] % (i + 100)); + } + String alphabet = this.alphabet; + final char ret = alphabet.charAt((int) (numberHashInt % alphabet.length())); + + long num; + long sepsIndex, guardIndex; + String buffer; + final StringBuilder ret_strB = new StringBuilder(this.minHashLength); + ret_strB.append(ret); + char guard; + + for (int i = 0; i < numbers.length; i++) { + num = numbers[i]; + buffer = ret + this.salt + alphabet; + + alphabet = HashIdsUtil.consistentShuffle(alphabet, buffer.substring(0, alphabet.length())); + final String last = HashIdsUtil.hash(num, alphabet); + + ret_strB.append(last); + + if (i + 1 < numbers.length) { + if (last.length() > 0) { + num %= (last.charAt(0) + i); + sepsIndex = (int) (num % this.seps.length()); + } else { + sepsIndex = 0; + } + ret_strB.append(this.seps.charAt((int) sepsIndex)); + } + } + + String ret_str = ret_strB.toString(); + if (ret_str.length() < this.minHashLength) { + guardIndex = (numberHashInt + (ret_str.charAt(0))) % this.guards.length(); + guard = this.guards.charAt((int) guardIndex); + + ret_str = guard + ret_str; + + if (ret_str.length() < this.minHashLength) { + guardIndex = (numberHashInt + (ret_str.charAt(2))) % this.guards.length(); + guard = this.guards.charAt((int) guardIndex); + + ret_str += guard; + } + } + + final int halfLen = alphabet.length() / 2; + while (ret_str.length() < this.minHashLength) { + alphabet = HashIdsUtil.consistentShuffle(alphabet, alphabet); + ret_str = alphabet.substring(halfLen) + ret_str + alphabet.substring(0, halfLen); + final int excess = ret_str.length() - this.minHashLength; + if (excess > 0) { + final int start_pos = excess / 2; + ret_str = ret_str.substring(start_pos, start_pos + this.minHashLength); + } + } + + return ret_str; + } + + private long[] _decode(String hash, String alphabet) { + final ArrayList ret = new ArrayList(); + + int i = 0; + final String regexp = "[" + this.guards + "]"; + String hashBreakdown = hash.replaceAll(regexp, " "); + String[] hashArray = hashBreakdown.split(" "); + + if (hashArray.length == 3 || hashArray.length == 2) { + i = 1; + } + + if (hashArray.length > 0) { + hashBreakdown = hashArray[i]; + if (!hashBreakdown.isEmpty()) { + final char lottery = hashBreakdown.charAt(0); + + hashBreakdown = hashBreakdown.substring(1); + hashBreakdown = hashBreakdown.replaceAll("[" + this.seps + "]", " "); + hashArray = hashBreakdown.split(" "); + + String subHash, buffer; + for (final String aHashArray : hashArray) { + subHash = aHashArray; + buffer = lottery + this.salt + alphabet; + alphabet = HashIdsUtil.consistentShuffle(alphabet, buffer.substring(0, alphabet.length())); + ret.add(HashIdsUtil.unhash(subHash, alphabet)); + } + } + } + + // transform from List to long[] + long[] arr = new long[ret.size()]; + for (int k = 0; k < arr.length; k++) { + arr[k] = ret.get(k); + } + + if (!this.encode(arr).equals(hash)) { + arr = new long[0]; + } + + return arr; + } + + private static String consistentShuffle(String alphabet, String salt) { + if (salt.length() <= 0) { + return alphabet; + } + + int asc_val, j; + final char[] tmpArr = alphabet.toCharArray(); + for (int i = tmpArr.length - 1, v = 0, p = 0; i > 0; i--, v++) { + v %= salt.length(); + asc_val = salt.charAt(v); + p += asc_val; + j = (asc_val + v + p) % i; + final char tmp = tmpArr[j]; + tmpArr[j] = tmpArr[i]; + tmpArr[i] = tmp; + } + + return new String(tmpArr); + } + + private static String hash(long input, String alphabet) { + String hash = ""; + final int alphabetLen = alphabet.length(); + + do { + final int index = (int) (input % alphabetLen); + if (index >= 0 && index < alphabet.length()) { + hash = alphabet.charAt(index) + hash; + } + input /= alphabetLen; + } while (input > 0); + + return hash; + } + + private static Long unhash(String input, String alphabet) { + long number = 0, pos; + + for (int i = 0; i < input.length(); i++) { + pos = alphabet.indexOf(input.charAt(i)); + number = number * alphabet.length() + pos; + } + + return number; + } + + /** + * Get Hashid algorithm version. + * + * @return Hashids algorithm version implemented. + */ + public String getVersion() { + return "1.0.0"; + } +} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/RateLimiterUtil.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/RateLimiterUtil.java index 06854b7..c47c2a8 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/RateLimiterUtil.java +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/RateLimiterUtil.java @@ -15,6 +15,8 @@ */ package org.opsli.common.utils; +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.core.util.StrUtil; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Maps; @@ -25,7 +27,6 @@ import org.opsli.common.thread.AsyncProcessExecutor; import org.opsli.common.thread.AsyncProcessExecutorFactory; import javax.servlet.http.HttpServletRequest; -import java.time.Duration; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -39,6 +40,8 @@ import java.util.concurrent.TimeUnit; @Slf4j public final class RateLimiterUtil { + /** 默认IP */ + public static final String DEFAULT_IP = "unknown"; /** 默认QPS */ public static final double DEFAULT_QPS = 10d; /** 默认缓存个数 超出后流量自动清理 */ @@ -46,7 +49,7 @@ public final class RateLimiterUtil { /** 默认缓存时效 超出后自动清理 */ private static final int DEFAULT_CACHE_TIME = 5; /** 默认等待时长 */ - private static final int DEFAULT_WAIT = 5000; + private static final int DEFAULT_WAIT = 500; /** 限流器单机缓存 */ private static final Cache > LFU_CACHE; @@ -108,6 +111,11 @@ public final class RateLimiterUtil { */ @SuppressWarnings("UnstableApiUsage") public static boolean enter(String clientIpAddress, String resource, Double dfQps) { + // IP 为空补偿器 + if(StrUtil.isBlank(clientIpAddress)){ + clientIpAddress = DEFAULT_IP; + } + // 计时器 long t1 = System.currentTimeMillis(); @@ -152,7 +160,7 @@ public final class RateLimiterUtil { RateLimiter rateLimiter = rateLimiterObj.getRateLimiter(); //非阻塞 - if (!rateLimiter.tryAcquire(Duration.ofMillis(DEFAULT_WAIT))) { + if (!rateLimiter.tryAcquire(DEFAULT_WAIT, TimeUnit.MILLISECONDS)) { //限速中,提示用户 log.error("限流器 - 访问频繁 耗时: "+ (System.currentTimeMillis() - t1) + "ms, IP地址: " + clientIpAddress + ", URI: " + resource); return false; @@ -183,18 +191,40 @@ public final class RateLimiterUtil { public static void main(String[] args) { - int count = 500; - RateLimiterUtil.removeIp("127.0.0.1"); - AsyncProcessExecutor normalExecutor = AsyncProcessExecutorFactory.createNormalExecutor(); - for (int i = 0; i < count; i++) { - normalExecutor.put(()->{ - boolean enter = RateLimiterUtil.enter("127.0.0.1","/api/v1", 2d); - System.out.println(enter); - }); +// int count = 500; +// RateLimiterUtil.removeIp("127.0.0.1"); +// AsyncProcessExecutor normalExecutor = AsyncProcessExecutorFactory.createNormalExecutor(); +// for (int i = 0; i < count; i++) { +// normalExecutor.put(()->{ +// RateLimiter rateLimiter = RateLimiter.create(1); +// +// +// boolean enter = RateLimiterUtil.enter("127.0.0.1","/api/v1", 2d); +// System.out.println(enter); +// }); +// } +// normalExecutor.execute(); + + + int count = 3; + RateLimiter rateLimiter = RateLimiter.create(count); + AsyncProcessExecutor normalExecutor = AsyncProcessExecutorFactory.createWaitExecutor(); + + int num = 0; + while (true){ + System.out.println("------------"+ (++num) +"------------"); + for (int i = 0; i < count+1; i++) { + normalExecutor.put(()->{ + boolean tryAcquire = rateLimiter.tryAcquire(500, TimeUnit.MILLISECONDS); + System.out.println(tryAcquire); + }); + } + normalExecutor.execute(); + ThreadUtil.sleep(1100); } - normalExecutor.execute(); } + } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/UniqueStrGeneratorUtils.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/UniqueStrGeneratorUtils.java new file mode 100644 index 0000000..0b4ccc3 --- /dev/null +++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/utils/UniqueStrGeneratorUtils.java @@ -0,0 +1,48 @@ +/** + * 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.utils; + +import cn.hutool.core.util.RandomUtil; + +/** + * 唯一字符串生成器 + * 参考 ... + * + * @author Parker + * @date 2022年07月11日 14:07 + */ +public final class UniqueStrGeneratorUtils { + + private static final String BEGIN_SALT = "opsli_2022_begin"; + private static final String END_SALT = "opsli_2022_end"; + private static final String CONTENT_SALT = "opsli_2022"; + + private static final HashIdsUtil DISTURB_HASH_ID_BEGIN = new HashIdsUtil(BEGIN_SALT, 2); + private static final HashIdsUtil DISTURB_HASH_ID_END = new HashIdsUtil(END_SALT, 3); + private static final HashIdsUtil CONTENT_HASH_ID = new HashIdsUtil(CONTENT_SALT, 7); + + + /** 生成 */ + public static String generator(long i) { + int begin = RandomUtil.randomInt(0, 10); + int end = RandomUtil.randomInt(10, 100); + String disturbHashIdBeginStr = DISTURB_HASH_ID_BEGIN.encode(begin); + String disturbHashIdEndStr = DISTURB_HASH_ID_END.encode(end); + String contentHashIdStr = CONTENT_HASH_ID.encode(i); + return disturbHashIdBeginStr + contentHashIdStr + disturbHashIdEndStr; + } + +} diff --git a/opsli-base-support/opsli-core/pom.xml b/opsli-base-support/opsli-core/pom.xml index c9fc99d..6b489e3 100644 --- a/opsli-base-support/opsli-core/pom.xml +++ b/opsli-base-support/opsli-core/pom.xml @@ -48,6 +48,13 @@ ${plugins.version} + + + org.opsliframework.boot + opsli-plugins-sms + ${plugins.version} + + org.opsliframework.boot @@ -55,6 +62,13 @@ ${plugins.version} + + + org.opsliframework.boot + opsli-plugins-security + ${plugins.version} + + org.opsliframework.boot @@ -78,12 +92,6 @@ - - - org.crazycake - shiro-redis-spring-boot-starter - - com.github.whvcse @@ -96,6 +104,11 @@ java-jwt + + com.jfinal + enjoy + + @@ -127,7 +140,20 @@ mysql mysql-connector-java + ${mysql.version} runtime + + + + com.google.protobuf + protobuf-java + + + + + + com.google.protobuf + protobuf-java @@ -149,6 +175,7 @@ org.postgresql postgresql runtime + ${postgresql.version} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/CorsConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/CorsConfig.java new file mode 100644 index 0000000..fbe9ee2 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/CorsConfig.java @@ -0,0 +1,46 @@ +/** + * 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 org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * Cors 跨域处理 + * + * @author Parker + * @date 2022年07月14日12:57:33 + **/ +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + /** + * 解决跨域问题 + * + * @param registry registry + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*") + .allowCredentials(true) + .maxAge(7200); + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/MyBatisPlusConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/MyBatisPlusConfig.java index 683c2c8..f9bc5fb 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/MyBatisPlusConfig.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/MyBatisPlusConfig.java @@ -15,7 +15,8 @@ */ package org.opsli.core.autoconfigure.conf; -import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.SqlSessionFactory; import org.opsli.core.filters.interceptor.MybatisAutoFillInterceptor; @@ -35,13 +36,20 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration public class MyBatisPlusConfig { - /*** - * 乐观锁 - * @return 拦截器 + /** + * 相关拦截器 */ @Bean - public OptimisticLockerInterceptor optimisticLockerInterceptor(){ - return new OptimisticLockerInterceptor(); + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); + + // 乐观锁 + mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); + + // 防止全表更新与删除插件 + //mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); + + return mybatisPlusInterceptor; } /** diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SecurityConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SecurityConfig.java new file mode 100644 index 0000000..84039da --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SecurityConfig.java @@ -0,0 +1,141 @@ +/** + * 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 cn.hutool.extra.spring.SpringUtil; +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import org.opsli.core.security.filter.JwtAuthenticationTokenFilter; +import org.opsli.core.security.service.UidUserDetailDetailServiceImpl; +import org.opsli.plugins.security.exception.handler.AccessDeniedHandlerImpl; +import org.opsli.plugins.security.exception.handler.AuthenticationEntryPointImpl; +import org.opsli.plugins.security.properties.AuthProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import java.util.List; +import java.util.Map; + + +/** + * Security 配置 + * + * @author Parker + * @date 2022年07月14日12:57:33 + **/ +@AllArgsConstructor +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled=true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + private final AuthProperties authProperties; + private final AccessDeniedHandlerImpl accessDeniedHandler; + private final AuthenticationEntryPointImpl authenticationEntryPoint; + private final UidUserDetailDetailServiceImpl uidUserDetailDetailService; + + + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers() + // 默认关闭 Security 的 xss防护,与系统本身的 xss防护冲突 + .xssProtection().disable() + // 允许Iframe加载 + .frameOptions().disable() + .and() + // 关闭csrf token认证不需要csrf防护 + .csrf().disable(); + + // 初始化 initAuthorizeRequests + this.initAuthorizeRequests(http); + } + + /** + * 设置 认证相关 URL + * @param http http + */ + private void initAuthorizeRequests(HttpSecurity http) throws Exception { + // 设置URL 未登陆前可访问URL + List anonymousList = authProperties.getUrlExclusion().getAnonymous(); + if(null != anonymousList){ + String[] urlExclusionArray = anonymousList.toArray(new String[0]); + http.authorizeRequests() + // URL 未登陆前可访问 + .antMatchers(urlExclusionArray).anonymous(); + } + + // 设置URL白名单 + List permitAll = authProperties.getUrlExclusion().getPermitAll(); + if(null != permitAll){ + String[] urlExclusionArray = permitAll.toArray(new String[0]); + http.authorizeRequests() + // URL 白名单 + .antMatchers(urlExclusionArray).permitAll(); + } + + // 除上面外的所有请求全部需要鉴权认证 + http.authorizeRequests() + .anyRequest().authenticated(); + + // 添加过滤器 + // 注意 自定义 Filter 不要交给 Spring管理 + http.addFilterBefore(new JwtAuthenticationTokenFilter(uidUserDetailDetailService), + UsernamePasswordAuthenticationFilter.class); + + // 异常处理 + http.exceptionHandling() + .accessDeniedHandler(accessDeniedHandler) + .authenticationEntryPoint(authenticationEntryPoint); + } + + /** + * 认证管理器 + */ + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + + @Override + protected AuthenticationManager authenticationManager() { + // 设置 多Provider + Map providerMap = + SpringUtil.getBeansOfType(AuthenticationProvider.class); + List authenticationProviderList = + Lists.newArrayListWithCapacity(providerMap.size()); + for (Map.Entry providerEntry : providerMap.entrySet()) { + authenticationProviderList.add(providerEntry.getValue()); + } + + ProviderManager authenticationManager = new ProviderManager(authenticationProviderList); + //不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException + authenticationManager.setEraseCredentialsAfterAuthentication(false); + return authenticationManager; + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/ShiroConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/ShiroConfig.java deleted file mode 100644 index 1322480..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/ShiroConfig.java +++ /dev/null @@ -1,198 +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 cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ClassUtil; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy; -import org.apache.shiro.authc.pam.ModularRealmAuthenticator; -import org.apache.shiro.mgt.SecurityManager; -import org.apache.shiro.realm.Realm; -import org.apache.shiro.session.mgt.SessionManager; -import org.apache.shiro.spring.LifecycleBeanPostProcessor; -import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; -import org.apache.shiro.spring.web.ShiroFilterFactoryBean; -import org.apache.shiro.web.mgt.DefaultWebSecurityManager; -import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; -import org.opsli.core.autoconfigure.properties.ApiPathProperties; -import org.opsli.core.autoconfigure.properties.GlobalProperties; -import org.opsli.core.security.shiro.authenticator.CustomModularRealmAuthenticator; -import org.opsli.core.security.shiro.filter.CustomShiroFilter; -import org.opsli.core.security.shiro.realm.FlagRealm; -import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; - -import javax.servlet.Filter; -import java.lang.reflect.Modifier; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Shiro配置 - * - * 全程用 token认证 所以也就用不着 什么共享缓存 - 无状态 - * - * @author Parker - * @date 2017-04-20 18:33 - */ -@Configuration -public class ShiroConfig { - - - /** - * filer - * @param securityManager 安全管理器 - * @return ShiroFilterFactoryBean - */ - @Bean("shiroFilter") - public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager, - GlobalProperties globalProperties, ApiPathProperties apiPathProperties) { - ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); - shiroFilter.setSecurityManager(securityManager); - - //oauth过滤 - Map filters = Maps.newHashMapWithExpectedSize(1); - filters.put("last_filter", new CustomShiroFilter()); - shiroFilter.setFilters(filters); - - Map filterMap = Maps.newLinkedHashMap(); - - // 加载排除URL - if(globalProperties.getAuth() != null && - globalProperties.getAuth().getToken() != null){ - Set urlExclusion = globalProperties.getAuth().getToken().getUrlExclusion(); - - if(CollUtil.isNotEmpty(urlExclusion)){ - for (String excUrl : urlExclusion) { - filterMap.put(excUrl, "anon"); - } - } - } - - // 登录接口拦截 - filterMap.put("/system/login", "anon"); - filterMap.put("/system/publicKey", "anon"); - filterMap.put("/system/slipCount", "anon"); - filterMap.put("/captcha*", "anon"); - - // 导出Excel\模版 不做自动拦截 手动拦截 - filterMap.put(apiPathProperties.getGlobalPrefix() + "/**/exportExcel", "anon"); - filterMap.put(apiPathProperties.getGlobalPrefix() + "/**/importExcel/template", "anon"); - - filterMap.put("/webjars/**", "anon"); - filterMap.put("/druid/**", "anon"); - filterMap.put("/app/**", "anon"); - filterMap.put("/swagger/**", "anon"); - filterMap.put("/v2/api-docs", "anon"); - filterMap.put("/doc.html", "anon"); - filterMap.put("/swagger-ui.html", "anon"); - filterMap.put("/swagger-resources/**", "anon"); - filterMap.put("/**", "last_filter"); - - shiroFilter.setFilterChainDefinitionMap(filterMap); - - return shiroFilter; - } - - @Bean("sessionManager") - public SessionManager sessionManager(){ - DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); - sessionManager.setSessionValidationSchedulerEnabled(true); - sessionManager.setSessionIdCookieEnabled(true); - return sessionManager; - } - - @Bean("securityManager") - public DefaultWebSecurityManager securityManager(SessionManager sessionManager) { - DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); - securityManager.setSessionManager(sessionManager); - // 设置验证器为自定义验证器 - securityManager.setAuthenticator(modularRealmAuthenticator()); - - List realms = Lists.newArrayList(); - // 拿到state包下 实现了 FlagRealm 接口的,所有子类 - Set> clazzSet = ClassUtil.scanPackageBySuper( - FlagRealm.class.getPackage().getName(), - FlagRealm.class - ); - for (Class aClass : clazzSet) { - // 位运算 去除抽象类 - if((aClass.getModifiers() & Modifier.ABSTRACT) != 0){ - continue; - } - - try { - realms.add((Realm) aClass.newInstance()); - } catch (Exception ignored){ } - } - - if(CollUtil.isNotEmpty(realms)){ - // 追加 Realms - securityManager.setRealms(realms); - } - - return securityManager; - } - - /** - * 针对多Realm,使用自定义身份验证器 - */ - @Bean("modularRealmAuthenticator") - public ModularRealmAuthenticator modularRealmAuthenticator(){ - CustomModularRealmAuthenticator authenticator = new CustomModularRealmAuthenticator(); - authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); - return authenticator; - } - - - - // ===================== 固定三板斧 ===================== - // 其实 没有 Spring Security 配置起来简单 - // - - @Bean("lifecycleBeanPostProcessor") - public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { - return new LifecycleBeanPostProcessor(); - } - - @Bean("defaultAdvisorAutoProxyCreator") - @DependsOn("lifecycleBeanPostProcessor") - public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { - DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator(); - proxyCreator.setProxyTargetClass(true); - proxyCreator.setUsePrefix(true); - proxyCreator.setAdvisorBeanNamePrefix("_no_advisor"); - return proxyCreator; - } - - /** - * 开启shiro权限注解生效 - * @param securityManager 安全管理器 - * @return AuthorizationAttributeSourceAdvisor - */ - @Bean("authorizationAttributeSourceAdvisor") - public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { - AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); - advisor.setSecurityManager(securityManager); - return advisor; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SpringWebMvcConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SpringWebMvcConfig.java index 0294838..34ca4ab 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SpringWebMvcConfig.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/SpringWebMvcConfig.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -67,23 +68,18 @@ public class SpringWebMvcConfig implements WebMvcConfigurer, WebMvcRegistrations /** * 解决跨域问题 - * @return CorsFilter + * + * @param registry registry */ - @Bean - public CorsFilter corsFilter() { - final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); - final CorsConfiguration corsConfiguration = new CorsConfiguration(); - /* 是否允许请求带有验证信息 */ - corsConfiguration.setAllowCredentials(true); - /* 允许访问的客户端域名 */ - corsConfiguration.addAllowedOrigin("*"); - /* 允许服务端访问的客户端请求头 */ - corsConfiguration.addAllowedHeader("*"); - /* 允许访问的方法名,GET POST等 */ - corsConfiguration.addAllowedMethod("*"); - urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); - return new CorsFilter(urlBasedCorsConfigurationSource); - } +// @Override +// public void addCorsMappings(CorsRegistry registry) { +// registry.addMapping("/**") +// .allowedOriginPatterns("*") +// .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") +// .allowedHeaders("*") +// .allowCredentials(true) +// .maxAge(7200); +// } @Override public void addInterceptors(InterceptorRegistry registry) { diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/GlobalProperties.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/GlobalProperties.java index 8cbfbd2..3dd4751 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/GlobalProperties.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/GlobalProperties.java @@ -90,9 +90,6 @@ public class GlobalProperties { /** 有效时间 (分钟)*/ private Integer effectiveTime; - /** 排除URL*/ - private Set urlExclusion; - } /** diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/TokenProperties.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/TokenProperties.java new file mode 100644 index 0000000..007fc5e --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/TokenProperties.java @@ -0,0 +1,43 @@ +/** + * 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.properties; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * Token配置 + * + * @author Parker + * @date 2020-09-15 + */ +@Component +@ConfigurationProperties(prefix = TokenProperties.PROP_PREFIX) +@Data +@EqualsAndHashCode(callSuper = false) +public class TokenProperties { + + public static final String PROP_PREFIX = "opsli.auth.token"; + + /** 盐 */ + private String secret; + + /** 有效时间 */ + private int effectiveTime; + +} 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 d822729..b61dd0b 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 @@ -16,7 +16,6 @@ package org.opsli.core.base.controller; -import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; @@ -24,36 +23,42 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.TimeInterval; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.CollectionUtils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; 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.RedisConstants; 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.utils.OutputStreamUtil; +import org.opsli.common.utils.UniqueStrGeneratorUtils; 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.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.persistence.querybuilder.QueryBuilder; +import org.opsli.core.persistence.querybuilder.WebQueryBuilder; 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.opsli.plugins.redis.RedisPlugin; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestParam; @@ -61,10 +66,11 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; -import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; +import java.io.Serializable; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Function; /** @@ -77,14 +83,8 @@ import java.util.function.Function; @RestController public abstract class BaseRestController >{ - /** 开启热点数据状态 */ - protected boolean hotDataFlag = false; - - /** Entity Clazz 类 */ - protected Class entityClazz; - /** Model Clazz 类 */ - protected Class modelClazz; - + /** 凭证 10分钟失效 */ + private static final int CERTIFICATE_EXPIRED_MINUTE = 10; /** 配置类 */ @Autowired @@ -94,6 +94,10 @@ public abstract class BaseRestController importExcel(MultipartHttpServletRequest request){ + protected ResultWrapper importExcel(MultipartHttpServletRequest request){ // 计时器 TimeInterval timer = DateUtil.timer(); Iterator itr = request.getFileNames(); @@ -119,21 +126,20 @@ public abstract class BaseRestController files = request.getFiles(uploadedFile); if (CollectionUtils.isEmpty(files)) { // 请选择文件 - return ResultVo.error(CoreMsg.EXCEL_FILE_NULL.getCode(), - CoreMsg.EXCEL_FILE_NULL.getMessage()); + return ResultWrapper.getCustomResultWrapper(CoreMsg.EXCEL_FILE_NULL); } - ResultVo resultVo ; + ResultWrapper resultVo ; String msgInfo; try { UserModel user = UserUtil.getUser(); Date currDate = DateUtil.date(); // 导入优化为 监听器 模式 超过一定阈值直接释放资源 防止导入数据导致系统 OOM - ExcelUtil.getInstance().readExcelByListener(files.get(0), modelClazz, new BatchExcelListener() { + ExcelUtil.getInstance().readExcelByListener(files.get(0), IService.getModelClass(), new BatchExcelListener() { @Override public void saveData(List dataList) { // 处理字典数据 - List disposeData = ExcelUtil.getInstance().handleDatas(dataList, modelClazz, ExcelOperate.READ); + List disposeData = ExcelUtil.getInstance().handleDatas(dataList, IService.getModelClass(), ExcelOperate.READ); // 手动赋值 必要数据 防止频繁开启Redis网络IO for (E model : disposeData) { model.setIzManual(true); @@ -152,7 +158,7 @@ public abstract class BaseRestController */ - protected void importTemplate(String fileName, HttpServletResponse response, Method method){ - this.excelExport(fileName + " 模版 ",null, response, method); + protected Optional excelExportAuth(String type, String subName, HttpServletRequest request){ + // 封装缓存数据 + ExcelExportCache exportCache; + if(ExcelExportCache.EXCEL_EXPORT.equals(type)){ + // 异常检测 + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); + QueryWrapper queryWrapper = queryBuilder.build(); + // 导出数量限制 -1 为无限制 + Integer exportMaxCount = globalProperties.getExcel().getExportMaxCount(); + if(exportMaxCount != null && exportMaxCount > -1){ + // 获得数量 大于 阈值 禁止导出, 防止OOM + long count = IService.count(queryWrapper); + if(count > exportMaxCount){ + String maxError = StrUtil.format(CoreMsg.EXCEL_HANDLE_MAX.getMessage(), count, + exportMaxCount); + // 超出最大导出数量 + throw new ExcelPluginException(CoreMsg.EXCEL_HANDLE_MAX.getCode(), maxError); + } + } + + // 封装缓存数据 + exportCache = ExcelExportCache.builder() + .subName(subName) + .parameterMapStr(JSONUtil.toJsonStr(request.getParameterMap())) + .type(type) + .build(); + }else if(ExcelExportCache.EXCEL_IMPORT_TEMPLATE_EXPORT.equals(type)){ + // 封装缓存数据 + exportCache = ExcelExportCache.builder() + .subName(subName+ " 模版 ") + .parameterMapStr(JSONUtil.toJsonStr(request.getParameterMap())) + .type(type) + .build(); + }else { + return Optional.empty(); + } + + + // 缓存Key + Long increment = redisPlugin + .increment(CacheUtil.formatKey(RedisConstants.PREFIX_TMP_EXCEL_EXPORT_NUM_NAME)); + String certificate = UniqueStrGeneratorUtils.generator(increment); + + // 缓存Key + String certificateCacheKeyTmp = CacheUtil.formatKey( + RedisConstants.PREFIX_TMP_EXCEL_EXPORT_NAME + certificate); + redisPlugin.put(certificateCacheKeyTmp, exportCache, CERTIFICATE_EXPIRED_MINUTE, TimeUnit.MINUTES); + + return Optional.of(certificate); } /** - * 导出 + * 导出 Excel * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param fileName 文件名称 - * @param queryWrapper 查询构建器 * @param response response */ - protected void excelExport(String fileName, QueryWrapper queryWrapper, HttpServletResponse response, - Method method){ - // 权限认证 - try { - if(method == null){ - // 无权访问该方法 - throw new TokenException(TokenMsg.EXCEPTION_NOT_AUTH); + protected void excelExport(String certificate, HttpServletResponse response){ + // 缓存Key + String certificateCacheKeyTmp = CacheUtil.formatKey( + RedisConstants.PREFIX_TMP_EXCEL_EXPORT_NAME + certificate); + Object cacheObj = redisPlugin.get(certificateCacheKeyTmp); + ExcelExportCache cache = Convert.convert(ExcelExportCache.class, cacheObj); + if(cache == null){ + return; + } - } + // 主题名称 + String subName = cache.getSubName(); - // Token 认证 - JwtRealm.authToken(); + List modelList = null; - RequiresPermissionsCus permissionsCus = method.getAnnotation(RequiresPermissionsCus.class); - if(permissionsCus != null){ - // 方法权限认证 - JwtRealm.authPerms(permissionsCus.value()); - } - }catch (TokenException e){ - // 推送错误信息 - OutputStreamUtil.exceptionResponse(e.getMessage(), response); - return; - } + // 如果导出Excel 需要查询数据 + if(ExcelExportCache.EXCEL_EXPORT.equals(cache.getType())){ + // 参数Map + Map parameterMap = new HashMap<>(); + JSONObject jsonObject = JSONUtil.parseObj(cache.getParameterMapStr()); + jsonObject.forEach((k, v) -> { + JSONArray values = (JSONArray) v; + String[] parameters = (String[]) values.toArray(String.class); + parameterMap.put(k, parameters); + }); - // 计时器 - TimeInterval timer = DateUtil.timer(); - String msgInfo; - ResultVo resultVo; - List modelList = Lists.newArrayList(); - try { - if(queryWrapper != null){ - // 导出数量限制 -1 为无限制 - Integer exportMaxCount = globalProperties.getExcel().getExportMaxCount(); - if(exportMaxCount != null && exportMaxCount > -1){ - // 获得数量 大于 阈值 禁止导出, 防止OOM - int count = IService.count(queryWrapper); - if(count > exportMaxCount){ - String maxError = StrUtil.format(CoreMsg.EXCEL_HANDLE_MAX.getMessage(), count, - exportMaxCount); - // 超出最大导出数量 - throw new ExcelPluginException(CoreMsg.EXCEL_HANDLE_MAX.getCode(), maxError); - } - } + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), parameterMap); + QueryWrapper queryWrapper = queryBuilder.build(); + List entityList = IService.findList(queryWrapper); + // 转化类型 + modelList = WrapperUtil.transformInstance(entityList, IService.getModelClass()); - List entityList = IService.findList(queryWrapper); - // 转化类型 - modelList = WrapperUtil.transformInstance(entityList, modelClazz); - } - // 导出Excel - ExcelUtil.getInstance().writeExcel(response, modelList ,fileName,"sheet", modelClazz ,ExcelTypeEnum.XLSX); - // 花费毫秒数 - long timerCount = timer.interval(); - // 提示信息 - msgInfo = StrUtil.format(CoreMsg.EXCEL_EXPORT_SUCCESS.getMessage(), modelList.size(), - DateUtil.formatBetween(timerCount)); - // 导出成功 - resultVo = ResultVo.success(msgInfo); - resultVo.setCode(CoreMsg.EXCEL_EXPORT_SUCCESS.getCode()); - } catch (ExcelPluginException e) { - // 花费毫秒数 - long timerCount = timer.interval(); - // 提示信息 - msgInfo = StrUtil.format(CoreMsg.EXCEL_EXPORT_ERROR.getMessage(), DateUtil.formatBetween(timerCount), e.getMessage()); - // 导出失败 - resultVo = ResultVo.error(CoreMsg.EXCEL_EXPORT_ERROR.getCode(), msgInfo); - }finally { - // 清空list - modelList.clear(); } - // 记录导出日志 - log.info(msgInfo); - // 导出异常 - if(!resultVo.isSuccess()){ - // 无权访问该方法 - OutputStreamUtil.exceptionResponse(resultVo.getMsg(), response); - } + // 导出Excel + ExcelUtil.getInstance().writeExcel( + response, modelList, subName,"sheet", IService.getModelClass() ,ExcelTypeEnum.XLSX); + + // 删除凭证 + redisPlugin.del(certificateCacheKeyTmp); } + /** * 演示模式 */ @@ -347,34 +359,28 @@ public abstract class BaseRestController modelClazz = this.modelClazz; - return modelClazz.newInstance(); - } catch (Exception e) { - log.error(e.getMessage(),e); - } - return null; - } + private static final long serialVersionUID = 1L; + public final static String EXCEL_IMPORT_TEMPLATE_EXPORT = "import-template-export"; + + public final static String EXCEL_EXPORT = "export"; + + + /** 主题名 */ + private String subName; + + /** 类型 */ + private String type; + + /** 请求参数Map */ + private String parameterMapStr; + + } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/dto/LoginUserDto.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/dto/LoginUserDto.java new file mode 100644 index 0000000..83f484b --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/dto/LoginUserDto.java @@ -0,0 +1,62 @@ +/** + * 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.base.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 当前登录用户信息 + * + * @author Parker + * @date 2021年12月22日16:22:37 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class LoginUserDto implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 用户ID */ + private String uid; + + /** 用户名 */ + private String username; + + /** 用户昵称 */ + private String nickname; + + /** 租户ID */ + private String tenantId; + + /** 手机 */ + private String mobile; + + /** 邮箱 */ + private String email; + + /** 登录来源: 0:PC端;1:APP-安卓 2:APP-IOS 3:小程序 */ + private String loginFrom; + + /** 登录ip */ + private String loginIp; +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/impl/CrudServiceImpl.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/impl/CrudServiceImpl.java index 08f2a38..f3e11f2 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/impl/CrudServiceImpl.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/impl/CrudServiceImpl.java @@ -16,10 +16,14 @@ package org.opsli.core.base.service.impl; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.TypeUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import com.baomidou.mybatisplus.core.toolkit.reflect.SpringReflectionHelper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageInfo; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; @@ -35,6 +39,7 @@ import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.chain.QueryDataPermsHandler; import org.opsli.core.persistence.querybuilder.chain.QueryTenantHandler; import org.opsli.core.persistence.querybuilder.conf.WebQueryConf; +import org.springframework.core.GenericTypeResolver; import org.springframework.transaction.annotation.Transactional; import javax.annotation.PostConstruct; @@ -64,12 +69,8 @@ import java.util.Map; public abstract class CrudServiceImpl, T extends BaseEntity, E extends ApiWrapper> extends BaseService implements CrudServiceInterface { - /** JSON tmp */ - private static final String JSON_TMP = "{\"id\":\"1\"}"; - /** Entity Clazz 类 */ - protected Class entityClazz; /** Model Clazz 类 */ - protected Class modelClazz; + protected Class modelClazz = getInnerModelClazz(); @Override public E get(String id) { @@ -213,7 +214,7 @@ public abstract class CrudServiceImpl, T extends BaseEnt @Override public List findList(QueryWrapper queryWrapper) { // 数据处理责任链 - QueryWrapper qWrapper = this.addHandler(entityClazz, queryWrapper); + QueryWrapper qWrapper = this.addHandler(this.getEntityClass(), queryWrapper); return super.list(qWrapper); } @@ -221,7 +222,7 @@ public abstract class CrudServiceImpl, T extends BaseEnt @Override public List findAllList() { // 数据处理责任链 - QueryWrapper qWrapper = this.addHandler(entityClazz); + QueryWrapper qWrapper = this.addHandler(this.getEntityClass()); return super.list(qWrapper); } @@ -229,7 +230,7 @@ public abstract class CrudServiceImpl, T extends BaseEnt @Override public Page findPage(Page page) { // 数据处理责任链 - QueryWrapper qWrapper = this.addHandler(entityClazz, page.getQueryWrapper()); + QueryWrapper qWrapper = this.addHandler(this.getEntityClass(), page.getQueryWrapper()); page.pageHelperBegin(); try{ List list = super.list(qWrapper); @@ -245,7 +246,7 @@ public abstract class CrudServiceImpl, T extends BaseEnt @Override public Page findPageNotCount(Page page) { // 数据处理责任链 - QueryWrapper qWrapper = this.addHandler(entityClazz, page.getQueryWrapper()); + QueryWrapper qWrapper = this.addHandler(this.getEntityClass(), page.getQueryWrapper()); page.pageHelperBegin(false); try{ List list = super.list(qWrapper); @@ -286,7 +287,7 @@ public abstract class CrudServiceImpl, T extends BaseEnt * @return T */ protected T transformM2T(E model){ - return WrapperUtil.transformInstance(model, entityClazz); + return WrapperUtil.transformInstance(model, this.getEntityClass()); } /** @@ -296,7 +297,7 @@ public abstract class CrudServiceImpl, T extends BaseEnt * @return List */ protected List transformMs2Ts(List models){ - return WrapperUtil.transformInstance(models, entityClazz); + return WrapperUtil.transformInstance(models, this.getEntityClass()); } /** @@ -342,26 +343,8 @@ public abstract class CrudServiceImpl, T extends BaseEnt // ======================== 初始化 ======================== - /** - * 初始化 - */ - @PostConstruct - public void init(){ - try { - this.modelClazz = this.getInnerModelClazz(); - this.entityClazz = this.getInnerEntityClazz(); - }catch (Exception e){ - log.error(e.getMessage(),e); - } - } - @Override - public Class getEntityClazz() { - return entityClazz; - } - - @Override - public Class getModelClazz() { + public Class getModelClass() { return modelClazz; } @@ -371,56 +354,8 @@ public abstract class CrudServiceImpl, T extends BaseEnt */ @SuppressWarnings("unchecked") public Class getInnerModelClazz(){ - String typeName = "E"; - Class tClass = null; - Map typeMap = TypeUtil.getTypeMap(this.getClass()); - for (Map.Entry typeTypeEntry : typeMap.entrySet()) { - Type entryKey = typeTypeEntry.getKey(); - Type entryValue = typeTypeEntry.getValue(); - - // 如果等于当前类型名称则进入 - if(entryKey != null && entryValue != null){ - if(StringUtils.equals(typeName, entryKey.getTypeName())){ - // 小技巧 json 转换 obj 然后 转换成 type对象 - Object convert = Convert.convert(entryValue, JSONObject.parse(JSON_TMP)); - if(convert instanceof ApiWrapper) { - tClass = (Class) entryValue; - break; - } - } - } - - } - return tClass; - } - - /** - * 内部获得 Entity 泛型 Clazz - * @return Class - */ - @SuppressWarnings("unchecked") - private Class getInnerEntityClazz(){ - String typeName = "T"; - Class tClass = null; - Map typeMap = TypeUtil.getTypeMap(this.getClass()); - for (Map.Entry typeTypeEntry : typeMap.entrySet()) { - Type entryKey = typeTypeEntry.getKey(); - Type entryValue = typeTypeEntry.getValue(); - - // 如果等于当前类型名称则进入 - if(entryKey != null && entryValue != null){ - if(StringUtils.equals(typeName, entryKey.getTypeName())){ - // 小技巧 json 转换 obj 然后 转换成 type对象 - Object convert = Convert.convert(entryValue, JSONObject.parse(JSON_TMP)); - if(convert instanceof ApiWrapper) { - tClass = (Class) entryValue; - break; - } - } - } - - } - return tClass; + Class[] typeArguments = GenericTypeResolver.resolveTypeArguments(this.getClass(), CrudServiceImpl.class); + return null == typeArguments ? null : (Class) typeArguments[2]; } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/interfaces/CrudServiceInterface.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/interfaces/CrudServiceInterface.java index 8c902fa..2be02a8 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/interfaces/CrudServiceInterface.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/service/interfaces/CrudServiceInterface.java @@ -44,6 +44,13 @@ import java.util.List; public interface CrudServiceInterface extends BaseServiceInterface { + /** + * 获得Model Class + * @return Class + */ + Class getModelClass(); + + /** * 获取单条数据 * @@ -201,19 +208,7 @@ public interface CrudServiceInterface */ Page findPageNotCount(Page page); - - - /** - * 获得Model Clazz - * @return Class - */ - Class getModelClazz(); - - /** - * 获得Entity Clazz - * @return Class - */ - Class getEntityClazz(); + } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java index c3dbc0f..98e574e 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java @@ -25,7 +25,9 @@ import com.google.common.util.concurrent.Striped; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; @@ -37,6 +39,8 @@ import java.util.function.Function; * 本地锁要优于分布式锁的速度,当然在秒杀系统还是要使用分布式锁的 * * 目前只支持 Redis 的 String 和 Hash + * 实际业务的话 这两种一般也是足够了 + * 依赖于 RedisTemplate 和 LRU cache,多套业务部署 最大穿透次数为 业务服务N次 * * @author Parker * @date 2021/12/10 12:39 @@ -373,6 +377,10 @@ public final class SecurityCache { throw new RuntimeException("入参[redisTemplate,key,callbackSource]必填"); } + // 先判断本地缓存是否存在 默认为存在(类似于伪布隆过滤) + if(isNonExist(key)){ + return null; + } // 缓存 Object 对象 Map cache = getAllHashCacheObject(redisTemplate, key, null); // 如果缓存不为空 则直接返回 @@ -387,6 +395,11 @@ public final class SecurityCache { try { // 尝试获得锁 if(lock.tryLock(DEFAULT_LOCK_TIME, TimeUnit.SECONDS)){ + // 先判断本地缓存是否存在 默认为存在(类似于伪布隆过滤) + if(isNonExist(key)){ + return null; + } + // 梅开二度 如果查到后 直接返回 cache = getAllHashCacheObject(redisTemplate, key, null); // 如果缓存不为空 则直接返回 @@ -588,48 +601,28 @@ public final class SecurityCache { /** - * 批量删除缓存 + * 删除缓存 * @param redisTemplate redisTemplate * @param keys 主键 */ - public static boolean removeMore( + public static boolean remove( final RedisTemplate redisTemplate, final String... keys) { if (null == redisTemplate || null == keys) { - throw new RuntimeException("入参[redisTemplate,keys]必填"); + throw new RuntimeException("入参[redisTemplate,key]必填"); } - int count = keys.length; + List removeKeyList = new ArrayList<>(); for (String key : keys) { - boolean isRemove = remove(redisTemplate, key); - if(isRemove){ - count--; - } - } - return 0 == count; - } + // 清除本地记录 + LFU_NULL_CACHE.invalidate(key); - /** - * 删除缓存 - * @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]必填"); + removeKeyList.add(StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV)); + removeKeyList.add(StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH)); } - // 清除本地记录 - 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); + redisTemplate.delete(removeKeyList); return true; } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/AbstractSpringEventBus.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/AbstractSpringEventBus.java new file mode 100644 index 0000000..266b92c --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/AbstractSpringEventBus.java @@ -0,0 +1,43 @@ +/** + * 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.eventbus; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * EventBus 与 Spring 打通桥梁 + * + * @author Parker + * @date 2021年12月7日10:39:16 + */ +public abstract class AbstractSpringEventBus implements IEventBus, ApplicationContextAware { + private ApplicationContext context; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.context = applicationContext; + this.scanConsumer(null); + } + + @Override + public void scanConsumer(String packageName) { + context.getBeansOfType(IEventConsumer.class).forEach((k,v)->{ + this.addConsumer(v); + }); + } +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/IEventBus.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/IEventBus.java new file mode 100644 index 0000000..01e6659 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/IEventBus.java @@ -0,0 +1,48 @@ +/** + * 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.eventbus; + +/** + * EventBus 接口 + * + * @author Parker + * @date 2021年12月7日10:38:24 + */ +public interface IEventBus { + /** + * 发布事件 + * @param event 事件实体 + */ + void post(Object event); + + /** + * 添加消费者 + * @param obj 消费者对象,默认以class为key + */ + void addConsumer(Object obj); + + /** + * 移除消费者 + * @param obj 消费者对象,默认以class为key + */ + void removeConsumer(Object obj); + + /** + * 扫描消费者 + * @param packageName 扫描包 + */ + void scanConsumer(String packageName); +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/utils/RedisKeys.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/IEventConsumer.java similarity index 59% rename from opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/utils/RedisKeys.java rename to opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/IEventConsumer.java index 30b7cfe..3bc24f8 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/utils/RedisKeys.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/eventbus/IEventConsumer.java @@ -1,5 +1,5 @@ /** - * Copyright 2018 人人开源 http://www.renren.io + * 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 @@ -13,22 +13,20 @@ * License for the specific language governing permissions and limitations under * the License. */ - -package org.opsli.core.security.shiro.utils; +package org.opsli.core.eventbus; /** - * Redis所有Keys + * EventBus 消费者接口 * - * @author Mark sunlightcs@gmail.com - * @since 3.0.0 2017-07-18 + * @author Parker + * @date 2020/9/25 12:19 */ -public class RedisKeys { +public interface IEventConsumer { - public static String getSysConfigKey(String key){ - return "system:config:" + key; - } + /** + * 消费者事件 + * @param event 事件 + */ + void consumer(T event); - public static String getShiroSessionKey(String key){ - return "sessionid:" + key; - } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LimiterAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LimiterAop.java index 2d395ce..7d4dbc3 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LimiterAop.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LimiterAop.java @@ -43,7 +43,7 @@ import static org.opsli.common.constants.OrderConstants.LIMITER_AOP_SORT; /** * 限流器 * - * @author 周鹏程 + * @author Parker * @date 2020-09-16 */ @Slf4j diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LogAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LogAop.java deleted file mode 100644 index 8d773eb..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LogAop.java +++ /dev/null @@ -1,75 +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.date.DateUtil; -import cn.hutool.core.date.TimeInterval; -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.opsli.core.utils.LogUtil; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import static org.opsli.common.constants.OrderConstants.TOKEN_AOP_SORT; - -/** - * 日志 拦截处理 - * - * @author parker - * @date 2020-09-16 - */ -@Slf4j -@Order(TOKEN_AOP_SORT) -@Aspect -@Component -public class LogAop { - - - @Pointcut("execution(public * org.opsli..*.*Controller*.*(..))") - public void requestMapping() { - } - - /** - * 切如 post 请求 - * @param point point - */ - @Around("requestMapping()") - public Object tokenAop(ProceedingJoinPoint point) throws Throwable { - // 计时器 - TimeInterval timer = DateUtil.timer(); - // 执行 - Exception exception = null; - // 防止线程抛异常 线程变量不回收 导致oom - Object returnValue; - try { - // 执行正常操作 - returnValue = point.proceed(); - }catch (Exception e){ - exception = e; - throw e; - } finally { - // 花费毫秒数 - long timerCount = timer.interval(); - //保存日志 - LogUtil.saveLog(point, exception, timerCount); - } - return returnValue; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LoginCryptoAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LoginCryptoAop.java deleted file mode 100644 index 59a48d6..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/LoginCryptoAop.java +++ /dev/null @@ -1,190 +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.bean.BeanUtil; -import cn.hutool.core.convert.Convert; -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; -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.LoginCrypto; -import org.opsli.common.exception.ServiceException; -import org.opsli.core.msg.CoreMsg; -import org.opsli.core.options.CryptoConfigFactory; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.Map; - -import static org.opsli.common.constants.OrderConstants.ENCRYPT_ADN_DECRYPT_AOP_SORT; - -/** - * 登录加解密 拦截处理 - * - * @author parker - * @date 2021-01-23 - */ -@Slf4j -@Order(ENCRYPT_ADN_DECRYPT_AOP_SORT) -@Aspect -@Component -public class LoginCryptoAop { - - @Pointcut("@annotation(org.opsli.common.annotation.LoginCrypto)") - public void encryptAndDecrypt() { - } - - /** - * 切如 post 请求 - * @param point point - */ - @Around("encryptAndDecrypt()") - public Object encryptAndDecryptHandle(ProceedingJoinPoint point) throws Throwable { - // 获得请求参数 - Object[] args = point.getArgs(); - // 返回结果 - Object returnValue; - - MethodSignature signature = (MethodSignature) point.getSignature(); - // 获得 方法 - Method method = signature.getMethod(); - // 获得方法注解 - LoginCrypto annotation = - method.getAnnotation(LoginCrypto.class); - - // 获得非对称加解密 执行器 - CryptoAsymmetricService asymmetric = null; - // 非对称加解密模型 - CryptoAsymmetric cryptoAsymmetric = null; - if(annotation != null && annotation.enable()){ - asymmetric = CryptoPlugin.getAsymmetric(); - cryptoAsymmetric = CryptoConfigFactory.INSTANCE.getCryptoAsymmetric(); - } - - // 1. 请求解密 - if(annotation != null && annotation.enable()){ - if(cryptoAsymmetric != null){ - enterDecrypt(args, method, asymmetric, cryptoAsymmetric); - } - } - - // 2. 执行方法 - returnValue = point.proceed(args); - - // 3. 返回加密 返回加密为对称加密 - if(annotation != null && annotation.enable()){ - if(cryptoAsymmetric != null){ - CryptoSymmetricService symmetric = CryptoPlugin.getSymmetric(); - CryptoSymmetric symmetricModel = symmetric.createNilModel(); - symmetricModel.setCryptoType(CryptoSymmetricType.DES); - symmetricModel.setPrivateKey(cryptoAsymmetric.getPublicKey()); - - // 执行加密操作 - returnValue = resultEncrypt(returnValue, symmetric, symmetricModel); - } - } - return returnValue; - } - - - - /** - * 入参解密 - * @param args 入参(集合) - * @param method 方法 - * @param asymmetric 非对称加解密执行器 - * @param cryptoModel 非对称加解密模型 - */ - private void enterDecrypt(Object[] args, Method method, CryptoAsymmetricService asymmetric, CryptoAsymmetric cryptoModel) { - for (int i = 0; i < args.length; i++) { - Object arg = args[i]; - // 参数校验 - if(arg instanceof BaseEncrypt){ - // 获得加密数据 - BaseEncrypt baseEncrypt = (BaseEncrypt) arg; - String encryptData = baseEncrypt.getEncryptData(); - // 解密对象 - Object dataToObj = asymmetric.decryptToObj(cryptoModel, encryptData); - - // 根据方法类型转化对象 - Type type = TypeUtil.getParamType(method, i); - Object obj = Convert.convert(type, dataToObj); - // 修改缓存中设备数据 空值不覆盖 - Map modelBeanMap = BeanUtil.beanToMap(obj); - modelBeanMap.entrySet().removeIf(entry -> entry.getValue() == null); - - // 反射赋值 - Field[] fields = ReflectUtil.getFields(arg.getClass()); - for (Field f : fields) { - Object val = modelBeanMap.get(f.getName()); - if(val == null){ - continue; - } - - //根据需要,将相关属性赋上默认值 - BeanUtil.setProperty(arg, f.getName(), val); - } - } - } - } - - - /** - * 出参加密 - * @param returnValue 出参(对象) - * @param symmetric 对称加解密执行器 - * @param cryptoModel 对称加解密模型 - * @return Object - */ - @SuppressWarnings("unchecked") - private Object resultEncrypt(Object returnValue, CryptoSymmetricService symmetric, CryptoSymmetric cryptoModel) { - if(returnValue != null){ - try { - // 执行加密过程 - if(returnValue instanceof ResultVo){ - // 重新赋值 data - ResultVo ret = (ResultVo) returnValue; - ret.setData( - symmetric.encrypt(cryptoModel, ret.getData()) - ); - }else { - returnValue = symmetric.encrypt(cryptoModel, returnValue); - } - }catch (Exception e){ - // 非对称加密失败 - throw new ServiceException(CoreMsg.OTHER_EXCEPTION_CRYPTO_EN); - } - } - return returnValue; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/SearchHisAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/SearchHisAop.java index 61aed30..4e81690 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/SearchHisAop.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/SearchHisAop.java @@ -38,7 +38,7 @@ import static org.opsli.common.constants.OrderConstants.SEARCH_HIS_AOP_SORT; /** * 搜索历史 AOP * - * @author 周鹏程 + * @author Parker * @date 2020-09-16 */ @Slf4j diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/interceptor/UserAuthInterceptor.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/interceptor/UserAuthInterceptor.java index 2fcf816..75ff107 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/interceptor/UserAuthInterceptor.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/interceptor/UserAuthInterceptor.java @@ -27,7 +27,7 @@ import javax.servlet.http.HttpServletResponse; /** * 用户权限拦截器,支持自解析 jwt token * - * @author 周鹏程 + * @author Parker * @date 2021年12月22日16:35:20 */ @Slf4j diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/handler/GlobalExceptionHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/handler/GlobalExceptionHandler.java index 6dabb71..637c748 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/handler/GlobalExceptionHandler.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/handler/GlobalExceptionHandler.java @@ -18,14 +18,9 @@ package org.opsli.core.handler; import cn.hutool.core.text.StrFormatter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authc.IncorrectCredentialsException; -import org.apache.shiro.authc.LockedAccountException; -import org.apache.shiro.authc.pam.UnsupportedTokenException; -import org.apache.shiro.authz.AuthorizationException; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.exception.*; import org.opsli.core.msg.CoreMsg; -import org.opsli.core.msg.TokenMsg; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @@ -86,9 +81,9 @@ public class GlobalExceptionHandler { @ExceptionHandler(ServiceException.class) @ResponseStatus(HttpStatus.OK) @ResponseBody - public ResultVo businessException(ServiceException e) { + public ResultWrapper businessException(ServiceException e) { log.warn("业务异常 - 异常编号:{} - 异常信息:{}",e.getCode(),e.getMessage()); - return ResultVo.error(e.getCode(), e.getMessage()); + return ResultWrapper.getCustomResultWrapper(e.getCode(), e.getMessage()); } /** @@ -97,8 +92,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(EmptyException.class) @ResponseStatus(HttpStatus.OK) @ResponseBody - public ResultVo emptyException(EmptyException e) { - return ResultVo.error(e.getCode(), e.getMessage()); + public ResultWrapper emptyException(EmptyException e) { + return ResultWrapper.getCustomResultWrapper(e.getCode(), e.getMessage()); } /** @@ -107,68 +102,19 @@ public class GlobalExceptionHandler { @ExceptionHandler(JwtException.class) @ResponseStatus(HttpStatus.OK) @ResponseBody - public ResultVo jwtException(JwtException e) { - return ResultVo.error(e.getCode(), e.getMessage()); + public ResultWrapper jwtException(JwtException e) { + return ResultWrapper.getCustomResultWrapper(e.getCode(), e.getMessage()); } - /** - * 拦截 自定义 Shiro 认证异常 - */ - @ExceptionHandler(IncorrectCredentialsException.class) - @ResponseStatus(HttpStatus.UNAUTHORIZED) - @ResponseBody - public ResultVo incorrectCredentialsException(IncorrectCredentialsException e) { - // token失效,请重新登录 - return ResultVo.error(e.getMessage()); - } - - /** - * 拦截 自定义 Shiro 认证异常 - */ - @ExceptionHandler(LockedAccountException.class) - @ResponseStatus(HttpStatus.OK) - @ResponseBody - public ResultVo lockedAccountException(LockedAccountException e) { - // 账号已被锁定,请联系管理员 - return ResultVo.error(e.getMessage()); - } - - /** - * 拦截 自定义 Shiro 认证异常 - */ - @ExceptionHandler(AuthorizationException.class) - @ResponseStatus(HttpStatus.OK) - @ResponseBody - public ResultVo authorizationException(AuthorizationException e) { - // 无权访问该方法 - return ResultVo.error(TokenMsg.EXCEPTION_NOT_AUTH.getCode(), - TokenMsg.EXCEPTION_NOT_AUTH.getMessage() - ); - } - - /** - * 拦截 自定义 Shiro 认证异常 - */ - @ExceptionHandler(UnsupportedTokenException.class) - @ResponseStatus(HttpStatus.OK) - @ResponseBody - public ResultVo unsupportedTokenException(UnsupportedTokenException e) { - // 找不到认证授权器 - return ResultVo.error(TokenMsg.EXCEPTION_NOT_REALM.getCode(), - TokenMsg.EXCEPTION_NOT_REALM.getMessage() - ); - } - - /** * 拦截 自定义 Token 认证异常 */ @ExceptionHandler(TokenException.class) @ResponseStatus(HttpStatus.OK) @ResponseBody - public ResultVo tokenException(TokenException e) { + public ResultWrapper tokenException(TokenException e) { // Token 异常 - return ResultVo.error(e.getCode(), e.getMessage()); + return ResultWrapper.getCustomResultWrapper(e.getCode(), e.getMessage()); } /** @@ -177,8 +123,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(WafException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody - public ResultVo wafException(WafException e) { - return ResultVo.error(e.getCode(), e.getMessage()); + public ResultWrapper wafException(WafException e) { + return ResultWrapper.getCustomResultWrapper(e.getCode(), e.getMessage()); } // ============================ @@ -189,9 +135,9 @@ public class GlobalExceptionHandler { @ExceptionHandler(NullPointerException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody - public ResultVo nullPointerException(NullPointerException e) { + public ResultWrapper nullPointerException(NullPointerException e) { log.error("空指针异常:{}",e.getMessage(),e); - return ResultVo.error(e.getMessage()); + return ResultWrapper.getErrorResultWrapper(); } @@ -201,9 +147,9 @@ public class GlobalExceptionHandler { @ExceptionHandler(SQLIntegrityConstraintViolationException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody - public ResultVo sqlIntegrityConstraintViolationException(EmptyException e) { + public ResultWrapper sqlIntegrityConstraintViolationException(EmptyException e) { log.error("数据异常:{}",e.getMessage(),e); - return ResultVo.error(e.getCode(), CoreMsg.SQL_EXCEPTION_INTEGRITY_CONSTRAINT_VIOLATION.getMessage()); + return ResultWrapper.getCustomResultWrapper(e.getCode(), CoreMsg.SQL_EXCEPTION_INTEGRITY_CONSTRAINT_VIOLATION.getMessage()); } /** @@ -212,17 +158,17 @@ public class GlobalExceptionHandler { @ExceptionHandler(SQLException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody - public ResultVo sqlException(SQLException e) { + public ResultWrapper sqlException(SQLException e) { //log.error("数据异常:{}",e.getMessage(),e); // 默认值异常 if(StringUtils.contains(e.getMessage(),SQL_EXCEPTION)){ String field = e.getMessage().replaceAll("Field '","") .replaceAll("' doesn't have a default value",""); String msg = StrFormatter.format(CoreMsg.SQL_EXCEPTION_NOT_HAVE_DEFAULT_VALUE.getMessage(), field); - return ResultVo.error(CoreMsg.SQL_EXCEPTION_NOT_HAVE_DEFAULT_VALUE.getCode(), msg); + return ResultWrapper.getCustomResultWrapper(CoreMsg.SQL_EXCEPTION_NOT_HAVE_DEFAULT_VALUE.getCode(), msg); } String msg = StrFormatter.format(CoreMsg.SQL_EXCEPTION_UNKNOWN.getMessage(), e.getMessage()); - return ResultVo.error(CoreMsg.SQL_EXCEPTION_UNKNOWN.getCode(), msg); + return ResultWrapper.getCustomResultWrapper(CoreMsg.SQL_EXCEPTION_UNKNOWN.getCode(), msg); } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/holder/UserContextHolder.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/holder/UserContextHolder.java index e584447..d139e64 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/holder/UserContextHolder.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/holder/UserContextHolder.java @@ -28,7 +28,7 @@ import java.util.Optional; /** * 用户认证信息上下文 * - * @author 周鹏程 + * @author Parker * @date 2021年12月22日16:22:59 */ public final class UserContextHolder { diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/annotation/OperateLogger.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/annotation/OperateLogger.java new file mode 100644 index 0000000..57f818a --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/annotation/OperateLogger.java @@ -0,0 +1,84 @@ +/** + * 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.log.annotation; + + +import org.opsli.core.log.enums.*; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * 日志注解 + * + * @author Parker + * @date 2021年7月15日20:28:24 + */ +@Target({ElementType.METHOD}) //注解作用于方法级别 +@Retention(RetentionPolicy.RUNTIME) //运行时起作用 +public @interface OperateLogger { + + /** + * 是否输出日志 + */ + boolean loggable() default true; + + /** + * 日志描述 + * 可使用占位符获取参数: ${tel} + */ + String description() default ""; + + /** + * 模块名称 + */ + ModuleEnum module() default ModuleEnum.MODULE_COMMON; + + /** + * 操作类型(enum):主要是 select,insert,update,delete + */ + OperationTypeEnum operationType() default OperationTypeEnum.UNKNOWN; + + /** + * 日志请求类型 + */ + LogTypeEnum type() default LogTypeEnum.BACKEND; + + /** + * 日志级别 + */ + LogLevelEnum level() default LogLevelEnum.INFO; + + /** + * 日志输出范围, 用于标记需要记录的日志信息范围,包含入参、返回值等 + * ALL-入参和出参, BEFORE-入参, AFTER-出参 + */ + LogScopeEnum scope() default LogScopeEnum.ALL; + + /** + * 是否存入数据库 + */ + boolean db() default false; + + /** + * 是否输出到控制台 + */ + boolean console() default true; + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/aspect/OperateLogAspect.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/aspect/OperateLogAspect.java new file mode 100644 index 0000000..fe5b2bf --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/aspect/OperateLogAspect.java @@ -0,0 +1,220 @@ +/** + * 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.log.aspect; + +import cn.hutool.json.JSONUtil; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +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.common.utils.MessUtil; +import org.opsli.core.base.dto.LoginUserDto; +import org.opsli.core.holder.UserContextHolder; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.bean.OperationLog; +import org.opsli.core.log.bus.OperationLogEventBus; +import org.opsli.core.log.enums.LogLevelEnum; +import org.opsli.core.log.enums.LogScopeEnum; +import org.opsli.core.utils.UserTokenUtil; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +/** + * 操作日志拦截器 + * + * @author Parker + * @date 2021年7月15日20:28:24 + */ +@Slf4j +@Aspect +@Component +@Order(50) +public class OperateLogAspect { + + /** 替换条件 */ + private static final String RE = "\\$\\{([\\w\\.\\-\\/\\+\\$\\#\\@\\!\\^\\&\\(\\)]+)\\}"; + + @Resource + private OperationLogEventBus operationLogEventBus; + + @Pointcut("@annotation(org.opsli.core.log.annotation.OperateLogger)") + public void operationLog(){} + + /** + * 环绕增强,相当于MethodInterceptor + */ + @Around("operationLog()") + public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { + Object result = null; + long time = System.currentTimeMillis(); + try { + result = joinPoint.proceed(); + return result; + } finally { + time = System.currentTimeMillis() - time; + try { + // 方法执行完成后增加日志 + addOperationLog(joinPoint, result, time); + }catch (Exception e){ + log.error("LogAspect 操作失败:{}" + e.getMessage()); + e.printStackTrace(); + } + } + } + + /** + * 添加日志 + * @param joinPoint point + * @param result 结果 + * @param time 时间 + */ + private void addOperationLog(JoinPoint joinPoint, Object result, long time){ + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + + OperateLogger annotation = signature.getMethod() + .getAnnotation(OperateLogger.class); + if(annotation == null || !annotation.loggable()){ + return; + } + + OperationLog operationLog = new OperationLog(); + + // 参数 + String argsStr = null; + try { + argsStr = JSONUtil.toJsonStr(joinPoint.getArgs()); + }catch (Exception ignored){} + // 结果 + String resultStr = null; + try { + resultStr = JSONUtil.toJsonStr(result); + }catch (Exception ignored){} + + if(LogScopeEnum.REQUEST.equals(annotation.scope())){ + operationLog.setArgs(argsStr); + } else if(LogScopeEnum.RESPONSE.equals(annotation.scope())){ + operationLog.setReturnValue(resultStr); + } else if(LogScopeEnum.ALL.equals(annotation.scope())){ + operationLog.setArgs(argsStr); + operationLog.setReturnValue(resultStr); + } + + operationLog.setId(UUID.randomUUID().toString()); + operationLog.setRunTime(time); + operationLog.setCreateTime(System.currentTimeMillis()); + operationLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName()); + + operationLog.setLevel(annotation.level().getValue()); + operationLog.setDescription( + // 对当前登录用户和占位符处理 + getDetail( + ((MethodSignature) joinPoint.getSignature()).getParameterNames(), + joinPoint.getArgs(), + annotation) + ); + operationLog.setOperationType(annotation.operationType().getValue()); + operationLog.setLogType(annotation.type().getValue()); + operationLog.setModuleId(annotation.module().getId()); + + // 当前Token + Optional tokenOptional = UserContextHolder.getToken(); + if(tokenOptional.isPresent()){ + LoginUserDto loginUserDto = UserTokenUtil.getLoginUserDto(tokenOptional.get()).orElse(null); + if(null != loginUserDto){ + operationLog.setUserId(String.valueOf(loginUserDto.getUid())); + operationLog.setUsername(loginUserDto.getUsername()); + operationLog.setRealName(loginUserDto.getNickname()); + operationLog.setTenantId(loginUserDto.getTenantId()); + } + } + + // 输出控制台 + if(annotation.console()){ + printToConsole(annotation.level(), operationLog); + } + // 存入数据库 + if(annotation.db()){ + operationLogEventBus.post(operationLog); + } + } + + /** + * 输出到控制台 + * @param level 等级 + * @param operationLog 日志 + */ + private void printToConsole(LogLevelEnum level, OperationLog operationLog){ + switch (level){ + case INFO: + log.info("记录日志:{}" , operationLog); + break; + case DEBUG: + log.debug("记录日志:{}" , operationLog); + break; + case WARN: + log.warn("记录日志:{}" , operationLog); + break; + case ERROR: + log.error("记录日志:{}" , operationLog); + break; + case TRACE: + log.trace("记录日志:{}" , operationLog); + break; + default: + break; + } + } + + /** + * 对当前登录用户和占位符处理 + * @param argNames 方法参数名称数组 + * @param args 方法参数数组 + * @param annotation 注解信息 + * @return 返回处理后的描述 + */ + private String getDetail(String[] argNames, Object[] args, OperateLogger annotation){ + Map map = Maps.newHashMap(); + for(int i = 0;i < argNames.length;i++){ + map.put(argNames[i], args[i]); + } + + String description = annotation.description(); + try { + // 当前用户信息 + Optional tokenOptional = UserContextHolder.getToken(); + if(tokenOptional.isPresent()){ + LoginUserDto loginUserDto = UserTokenUtil.getLoginUserDto(tokenOptional.get()).orElse(null); + if(null != loginUserDto){ + description = "'" + loginUserDto.getNickname() + "'=> " + annotation.description(); + } + } + description = MessUtil.getMes(description, RE, "${", "}", map); + }catch (Exception e){ + e.printStackTrace(); + } + return description; + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/bean/OperationLog.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/bean/OperationLog.java new file mode 100644 index 0000000..9c23ea7 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/bean/OperationLog.java @@ -0,0 +1,82 @@ +/** + * 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.log.bean; + +import lombok.Data; +import lombok.ToString; + +import java.io.Serializable; + +/** + * 操作日志 + * + * @author Parker + * @date 2021年7月15日20:28:24 + */ +@Data +@ToString +public class OperationLog implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 日志ID */ + private String id; + + /** 创建时间 */ + private long createTime; + + /** 日志等级 */ + private String level; + + /** 被操作的系统模块 */ + private String moduleId; + + /** 方法名 */ + private String method; + + /** 参数 */ + private String args; + + /** 操作人id */ + private String userId; + + /** 操作人用户名 */ + private String username; + + /** 真实姓名 */ + private String realName; + + /** 日志描述 */ + private String description; + + /** 操作类型 */ + private String operationType; + + /** 方法运行时间 */ + private Long runTime; + + /** 方法返回值 */ + private String returnValue; + + /** 租户ID */ + private String tenantId; + + /** + * 日志请求类型 + */ + private String logType; + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/bus/OperationLogEventBus.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/bus/OperationLogEventBus.java new file mode 100644 index 0000000..4c09676 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/bus/OperationLogEventBus.java @@ -0,0 +1,72 @@ +/** + * 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.log.bus; + +import com.google.common.eventbus.AsyncEventBus; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.SubscriberExceptionContext; +import com.google.common.eventbus.SubscriberExceptionHandler; +import lombok.extern.slf4j.Slf4j; +import org.opsli.common.thread.ThreadPoolFactory; +import org.opsli.core.eventbus.AbstractSpringEventBus; +import org.springframework.stereotype.Component; + +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 操作日志事件 总线 + * @author 周鹏程 + * @date 2021年12月7日10:42:39 + */ +@Component +@Slf4j +public class OperationLogEventBus extends AbstractSpringEventBus implements SubscriberExceptionHandler { + + private final EventBus eventBus; + + public OperationLogEventBus() { + // 异步事件配置线程池 + eventBus = new AsyncEventBus( + ThreadPoolFactory.createInitThreadPool(5, 10, 60, TimeUnit.SECONDS, + 1024, "Operation-Log-Event-Bus", + new ThreadPoolExecutor.CallerRunsPolicy() + ) + , this + ); + } + + @Override + public void post(Object event) { + eventBus.post(event); + } + + @Override + public void addConsumer(Object obj) { + eventBus.register(obj); + } + + @Override + public void removeConsumer(Object obj) { + eventBus.unregister(obj); + } + + @Override + public void handleException(Throwable exception, SubscriberExceptionContext context) { + log.error("user event handler exception", exception); + } + +} diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/RequiresPermissionsCus.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogLevelEnum.java similarity index 62% rename from opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/RequiresPermissionsCus.java rename to opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogLevelEnum.java index ef3a330..359f71f 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/RequiresPermissionsCus.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogLevelEnum.java @@ -13,23 +13,29 @@ * License for the specific language governing permissions and limitations under * the License. */ -package org.opsli.common.annotation; +package org.opsli.core.log.enums; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import lombok.AllArgsConstructor; +import lombok.Getter; /** - * 自定义权限验证 + * 日志级别枚举 * * @author Parker - * @date 2020-09-22 17:07 + * @date 2021年7月15日20:28:24 */ -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface RequiresPermissionsCus { +@Getter +@AllArgsConstructor +public enum LogLevelEnum { - String[] value(); + /** + * 日志级别枚举 + */ + DEBUG("-1"), + INFO("0"), + WARN("1"), + ERROR("2"), + TRACE("3"); + private final String value; } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/LoginCrypto.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogScopeEnum.java similarity index 63% rename from opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/LoginCrypto.java rename to opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogScopeEnum.java index 6ab9e2a..2989ffa 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/LoginCrypto.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogScopeEnum.java @@ -13,25 +13,31 @@ * License for the specific language governing permissions and limitations under * the License. */ -package org.opsli.common.annotation; - - -import java.lang.annotation.*; +package org.opsli.core.log.enums; /** - * 登录加解密 - * 入参 非对称 公钥加密 私钥解密 - * 出参 对称 公要加密 公要解密 + * 日志记录范围 * * @author Parker - * @date 2021年5月18日14:46:02 + * @date 2021年7月15日20:28:24 */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface LoginCrypto { +public enum LogScopeEnum { + + /** + * 日志记录范围 + */ + ALL(0), + REQUEST(1), + RESPONSE(2) + ; + + private final int value; - /** 加密启用状态 */ - boolean enable() default true; + public int getValue() { + return value; + } + LogScopeEnum(int value) { + this.value = value; + } } diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/EnableLog.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogTypeEnum.java similarity index 58% rename from opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/EnableLog.java rename to opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogTypeEnum.java index 0ac42ab..6085e62 100644 --- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/annotation/EnableLog.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/LogTypeEnum.java @@ -13,25 +13,36 @@ * License for the specific language governing permissions and limitations under * the License. */ -package org.opsli.common.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +package org.opsli.core.log.enums; /** - * 自定义操作日志注解 - * @author parker - * @date 2020-09-12 + * 日志类型 + * + * @author Parker + * @date 2021年7月15日20:28:24 */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface EnableLog { +public enum LogTypeEnum { + + /** WEB */ + WEB("0"), + + /** 客户端 */ + CLIENT("1"), + + /** 后端 */ + BACKEND("2"), + + /** 程序自动 */ + AUTO("3") + ; + + private final String value; - /** 标题 */ - String title() default ""; + public String getValue() { + return value; + } + LogTypeEnum(String value) { + this.value = value; + } } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/ModuleEnum.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/ModuleEnum.java new file mode 100644 index 0000000..567e72b --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/ModuleEnum.java @@ -0,0 +1,66 @@ +/** + * 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.log.enums; + + +/** + * 模块字典 + * + * @author Parker + * @date 2021年7月15日20:19:27 + */ +public enum ModuleEnum { + + /** 模块 */ + MODULE_UNKNOWN("-1", "未知(请配置模块)"), + MODULE_COMMON("00", "公共模块"), + MODULE_USER("01", "用户模块"), + MODULE_ROLE("02", "角色模块"), + MODULE_MENU("03", "菜单模块"), + MODULE_ORG("04", "组织模块"), + MODULE_DICT("05", "字典模块"), + MODULE_TENANT("06", "租户模块"), + MODULE_AREA("07", "地区模块"), + MODULE_MONITOR("08", "监控模块"), + MODULE_GENERATOR("09", "代码生成器"), + + MODULE_OPERATION("11", "行为日志"), + + + MODULE_TEST("100", "测试模块"), + MODULE_TEST_USER("101", "测试用户模块"), + MODULE_TEST_CAR("102", "测试汽车模块"), + + + ; + + private final String id; + private final String name; + + ModuleEnum(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/OperationTypeEnum.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/OperationTypeEnum.java new file mode 100644 index 0000000..2ffe541 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/log/enums/OperationTypeEnum.java @@ -0,0 +1,48 @@ +/** + * 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.log.enums; + +/** + * 操作类型 + * + * @author Parker + * @date 2021年7月15日20:27:27 + */ +public enum OperationTypeEnum { + /** + * 操作类型 + */ + UNKNOWN("unknown"), + DELETE("delete"), + SELECT("select"), + UPDATE("update"), + INSERT("insert"); + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + OperationTypeEnum(String s) { + this.value = s; + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/msg/TokenMsg.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/msg/TokenMsg.java index c22fbac..65f6ef3 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/msg/TokenMsg.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/msg/TokenMsg.java @@ -30,14 +30,20 @@ public enum TokenMsg implements BaseMsg { */ EXCEPTION_TOKEN_CREATE_ERROR(12000,"生成Token失败"), EXCEPTION_TOKEN_CREATE_LIMIT_ERROR(12001,"您的账号已在其他设备登录"), - EXCEPTION_TOKEN_LOSE_EFFICACY(401,"Token失效,请重新登录"), + EXCEPTION_TOKEN_LOSE_EFFICACY(401,"凭证已过期,请重新登陆"), + + AUTH_CREDENTIALS_INVALID(100208, "凭证已过期,请重新登陆"), + AUTH_AUTH_INVALID(100209, "认证失败,请重新登陆"), /** * 登陆 */ + EXCEPTION_CAPTCHA_CERTIFICATE_ERROR(12097, "凭证验证失败,请刷新重试"), + EXCEPTION_CAPTCHA_ARGS_NULL(12098, "参数异常"), + EXCEPTION_CAPTCHA_OFTEN(12099, "已获取验证码,请勿频繁获取"), EXCEPTION_CAPTCHA_ERROR(12100,"验证码不正确!"), - EXCEPTION_CAPTCHA_NULL(12201, "验证码已失效"), + EXCEPTION_CAPTCHA_NULL(12201, "验证码已失效, 请重新生成"), EXCEPTION_CAPTCHA_UUID_NULL(12202, "验证码UUID为空"), EXCEPTION_CAPTCHA_CODE_NULL(12203, "验证码为空"), EXCEPTION_LOGIN_ACCOUNT_NO(12101,"账号或密码不正确!"), diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/filter/JwtAuthenticationTokenFilter.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..ef8348e --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,81 @@ +/** + * 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.security.filter; + +import lombok.AllArgsConstructor; +import org.opsli.core.base.dto.LoginUserDto; +import org.opsli.core.security.service.UidUserDetailDetailServiceImpl; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.plugins.security.authentication.AfterAuthenticationToken; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * JWT 认证 拦截器 + * 注: 不要降 自定义filter 交给 Spring管理 + * @author Parker + * @date 2022年07月22日16:16:42 + */ +@AllArgsConstructor +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { + + private final UidUserDetailDetailServiceImpl uidUserDetailDetailService; + + @Override + protected void doFilterInternal( + HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + // 获取token + String token = UserTokenUtil.getRequestToken(request); + if (!StringUtils.hasText(token)) { + //放行 + filterChain.doFilter(request, response); + return; + } + + // 验证Token + UserTokenUtil.verify(token); + + // 获得登陆用户信息 + LoginUserDto loginUserDto = UserTokenUtil.getLoginUserDto(token) + // 认证无效 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID)); + + // 这里用Uid 获取用户信息,因为涉及到超管切换租户身份 + // 非 租户系统 可以直接使用 用户名获取信息 + UserDetails userDetails = uidUserDetailDetailService.loadUserByPrincipal(loginUserDto.getUid()) + // 认证无效 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID)); + + AfterAuthenticationToken authenticationToken = + new AfterAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + + //放行 + filterChain.doFilter(request, response); + } +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/EmailUserDetailDetailServiceImpl.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/EmailUserDetailDetailServiceImpl.java new file mode 100644 index 0000000..e2830a3 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/EmailUserDetailDetailServiceImpl.java @@ -0,0 +1,108 @@ +/** + * 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.security.service; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.enums.DictType; +import org.opsli.core.utils.UserUtil; +import org.opsli.plugins.security.UserDetailModel; +import org.opsli.plugins.security.authentication.EmailCodeAuthenticationToken; +import org.opsli.plugins.security.authentication.EmailPasswordAuthenticationToken; +import org.opsli.plugins.security.properties.AuthProperties; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 邮箱+验证码 获取用户信息Service + * 实际只需要用到 邮箱唯一主键即可 + * + * @author Parker + * @date 2022-07-14 4:44 PM + **/ +@AllArgsConstructor +@Service +public class EmailUserDetailDetailServiceImpl implements ILoadUserDetailService { + + private static final String DEFAULT_ROLE_PREFIX = "ROLE_"; + private final AuthProperties authProperties; + + @Override + public Collection> getClassTypes() { + List> classes = new ArrayList<>(); + classes.add(EmailCodeAuthenticationToken.class); + classes.add(EmailPasswordAuthenticationToken.class); + return classes; + } + + @Override + public Optional loadUserByPrincipal(Object principal) { + UserModel userModel = UserUtil.getUserByEmail((String) principal); + if(null == userModel){ + return Optional.empty(); + } + + // 处理权限数据 + List authorities = new ArrayList<>(); + List userRoles = UserUtil.getUserRolesByUserId(userModel.getId()); + List userAllPerms = UserUtil.getUserAllPermsByUserId(userModel.getId()); + for (String userRole : userRoles) { + authorities.add(DEFAULT_ROLE_PREFIX+userRole); + } + authorities.addAll(userAllPerms); + + // 清除空的 授权 + authorities.removeIf(StrUtil::isEmpty); + + List grantedAuthorities = authorities.stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + UserDetailModel userDetailModel = UserDetailModel.builder() + .username(userModel.getUsername()) + .password(userModel.getPassword()) + // 账户启动 + .enabled( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未过期(如果需要 请自行扩展字段) + .accountNonExpired( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未锁定(如果需要 请自行扩展字段) + .accountNonLocked( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 判断凭证是否过期(默认不判断 如果需要 请自行扩展过期后修改密码操作) + .credentialsNonExpired( + PasswordUtil.isCredentialsNonExpired( + userModel.getPassword(), authProperties.getCredentialsExpired())) + // 授权信息 + .authorities(grantedAuthorities) + .build(); + + return Optional.ofNullable(userDetailModel); + } + + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/MobileUserDetailDetailServiceImpl.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/MobileUserDetailDetailServiceImpl.java new file mode 100644 index 0000000..7fd9463 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/MobileUserDetailDetailServiceImpl.java @@ -0,0 +1,110 @@ +/** + * 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.security.service; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.enums.DictType; +import org.opsli.core.utils.UserUtil; +import org.opsli.plugins.security.UserDetailModel; +import org.opsli.plugins.security.authentication.MobileCodeAuthenticationToken; +import org.opsli.plugins.security.authentication.MobilePasswordAuthenticationToken; +import org.opsli.plugins.security.properties.AuthProperties; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 手机号+验证码 获取用户信息Service + * 实际只需要用到 手机号唯一主键即可 + * + * @author Parker + * @date 2022-07-14 4:44 PM + **/ +@AllArgsConstructor +@Service +public class MobileUserDetailDetailServiceImpl implements ILoadUserDetailService { + + private static final String DEFAULT_ROLE_PREFIX = "ROLE_"; + private final AuthProperties authProperties; + + @Override + public Collection> getClassTypes() { + List> classes = new ArrayList<>(); + classes.add(MobileCodeAuthenticationToken.class); + classes.add(MobilePasswordAuthenticationToken.class); + return classes; + } + + @Override + public Optional loadUserByPrincipal(Object principal) { + UserModel userModel = UserUtil.getUserByMobile((String) principal); + if(null == userModel){ + return Optional.empty(); + } + + // 处理权限数据 + List authorities = new ArrayList<>(); + List userRoles = UserUtil.getUserRolesByUserId(userModel.getId()); + List userAllPerms = UserUtil.getUserAllPermsByUserId(userModel.getId()); + for (String userRole : userRoles) { + authorities.add(DEFAULT_ROLE_PREFIX+userRole); + } + authorities.addAll(userAllPerms); + + // 清除空的 授权 + authorities.removeIf(StrUtil::isEmpty); + + List grantedAuthorities = authorities.stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + UserDetailModel userDetailModel = UserDetailModel.builder() + .username(userModel.getUsername()) + .password(userModel.getPassword()) + // 账户启动 + .enabled( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未过期(如果需要 请自行扩展字段) + .accountNonExpired( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未锁定(如果需要 请自行扩展字段) + .accountNonLocked( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 判断凭证是否过期(默认不判断 如果需要 请自行扩展过期后修改密码操作) + .credentialsNonExpired( + PasswordUtil.isCredentialsNonExpired( + userModel.getPassword(), authProperties.getCredentialsExpired())) + // 授权信息 + .authorities(grantedAuthorities) + .build(); + + return Optional.ofNullable(userDetailModel); + } + + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/UidUserDetailDetailServiceImpl.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/UidUserDetailDetailServiceImpl.java new file mode 100644 index 0000000..1a88f55 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/UidUserDetailDetailServiceImpl.java @@ -0,0 +1,102 @@ +/** + * 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.security.service; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.enums.DictType; +import org.opsli.core.utils.UserUtil; +import org.opsli.plugins.security.UserDetailModel; +import org.opsli.plugins.security.properties.AuthProperties; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 用户ID 获取用户信息Service + * + * @author Parker + * @date 2022-07-14 4:44 PM + **/ +@AllArgsConstructor +@Service("uidUserDetailDetailService") +public class UidUserDetailDetailServiceImpl implements ILoadUserDetailService { + + private static final String DEFAULT_ROLE_PREFIX = "ROLE_"; + private final AuthProperties authProperties; + + @Override + public Collection> getClassTypes() { + // 为空则不会进入 Token 工厂内 + return null; + } + + @Override + public Optional loadUserByPrincipal(Object principal) { + UserModel userModel = UserUtil.getUser((String) principal); + if(null == userModel){ + return Optional.empty(); + } + + // 处理权限数据 + List authorities = new ArrayList<>(); + List userRoles = UserUtil.getUserRolesByUserId(userModel.getId()); + List userAllPerms = UserUtil.getUserAllPermsByUserId(userModel.getId()); + for (String userRole : userRoles) { + authorities.add(DEFAULT_ROLE_PREFIX+userRole); + } + authorities.addAll(userAllPerms); + + // 清除空的 授权 + authorities.removeIf(StrUtil::isEmpty); + + List grantedAuthorities = authorities.stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + UserDetailModel userDetailModel = UserDetailModel.builder() + .username(userModel.getUsername()) + .password(userModel.getPassword()) + // 账户启动 + .enabled( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未过期(如果需要 请自行扩展字段) + .accountNonExpired( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未锁定(如果需要 请自行扩展字段) + .accountNonLocked( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 判断凭证是否过期(默认不判断 如果需要 请自行扩展过期后修改密码操作) + .credentialsNonExpired( + PasswordUtil.isCredentialsNonExpired( + userModel.getPassword(), authProperties.getCredentialsExpired())) + // 授权信息 + .authorities(grantedAuthorities) + .build(); + + return Optional.ofNullable(userDetailModel); + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/UsernameUserDetailDetailServiceImpl.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/UsernameUserDetailDetailServiceImpl.java new file mode 100644 index 0000000..89bdf15 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/service/UsernameUserDetailDetailServiceImpl.java @@ -0,0 +1,102 @@ +/** + * 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.security.service; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.enums.DictType; +import org.opsli.core.utils.UserUtil; +import org.opsli.plugins.security.UserDetailModel; +import org.opsli.plugins.security.properties.AuthProperties; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 用户名+密码 获取用户信息Service + * 实际只需要用到 用户名唯一主键即可 + * + * @author Parker + * @date 2022-07-14 4:44 PM + **/ +@AllArgsConstructor +@Service("usernameUserDetailDetailService") +public class UsernameUserDetailDetailServiceImpl implements ILoadUserDetailService { + + private static final String DEFAULT_ROLE_PREFIX = "ROLE_"; + private final AuthProperties authProperties; + + @Override + public Collection> getClassTypes() { + return Collections.singleton(UsernamePasswordAuthenticationToken.class); + } + + @Override + public Optional loadUserByPrincipal(Object principal) { + UserModel userModel = UserUtil.getUserByUserName((String) principal); + if(null == userModel){ + return Optional.empty(); + } + + // 处理权限数据 + List authorities = new ArrayList<>(); + List userRoles = UserUtil.getUserRolesByUserId(userModel.getId()); + List userAllPerms = UserUtil.getUserAllPermsByUserId(userModel.getId()); + for (String userRole : userRoles) { + authorities.add(DEFAULT_ROLE_PREFIX+userRole); + } + authorities.addAll(userAllPerms); + + // 清除空的 授权 + authorities.removeIf(StrUtil::isEmpty); + + List grantedAuthorities = authorities.stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + UserDetailModel userDetailModel = UserDetailModel.builder() + .username(userModel.getUsername()) + .password(userModel.getPassword()) + // 账户启动 + .enabled( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未过期(如果需要 请自行扩展字段) + .accountNonExpired( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 账户未锁定(如果需要 请自行扩展字段) + .accountNonLocked( + DictType.NO_YES_YES.getValue().equals(userModel.getEnable())) + // 判断凭证是否过期(默认不判断 如果需要 请自行扩展过期后修改密码操作) + .credentialsNonExpired( + PasswordUtil.isCredentialsNonExpired( + userModel.getPassword(), authProperties.getCredentialsExpired())) + // 授权信息 + .authorities(grantedAuthorities) + .build(); + + return Optional.ofNullable(userDetailModel); + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/authenticator/CustomModularRealmAuthenticator.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/authenticator/CustomModularRealmAuthenticator.java deleted file mode 100644 index 4277aec..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/authenticator/CustomModularRealmAuthenticator.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.opsli.core.security.shiro.authenticator; - -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.pam.ModularRealmAuthenticator; -import org.apache.shiro.authc.pam.UnsupportedTokenException; -import org.apache.shiro.realm.Realm; - -import java.util.Collection; - -/** - * 自定义身份验证器,根据登录使用的Token匹配调用对应的Realm - * - * @author Parker - * @date 2020-09-16 - */ -public class CustomModularRealmAuthenticator extends ModularRealmAuthenticator { - - /** - * 自定义Realm的分配策略 - * 通过realm.supports()方法匹配对应的Realm,因此才要在Realm中重写supports()方法 - * @param realms realm 集合 - * @param token token - * @return AuthenticationInfo - */ - @Override - protected AuthenticationInfo doMultiRealmAuthentication(Collection realms, AuthenticationToken token) { - // 判断getRealms()是否返回为空 - assertRealmsConfigured(); - - // 通过supports()方法,匹配对应的Realm - Realm uniqueRealm = null; - for (Realm realm : realms) { - if (realm.supports(token)) { - uniqueRealm = realm; - break; - } - } - - if (uniqueRealm == null) { - throw new UnsupportedTokenException(); - } - return uniqueRealm.getAuthenticationInfo(token); - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisCache.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisCache.java deleted file mode 100644 index ec51a9f..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisCache.java +++ /dev/null @@ -1,256 +0,0 @@ -package org.opsli.core.security.shiro.cache; - - -import org.apache.shiro.cache.Cache; -import org.apache.shiro.cache.CacheException; -import org.apache.shiro.subject.PrincipalCollection; -import org.apache.shiro.util.CollectionUtils; -import org.opsli.core.security.shiro.exception.PrincipalIdNullException; -import org.opsli.core.security.shiro.exception.PrincipalInstanceException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.*; - -/** - * @author: sunzhiqiang - * @date: 2018/6/22 - * @description: 参考 shiro-redis 开源项目 Git地址 https://github.com/alexxiyang/shiro-redis - */ -public class RedisCache implements Cache { - - private static Logger logger = LoggerFactory.getLogger(RedisCache.class); - - private RedisManager redisManager; - private String keyPrefix = ""; - private int expire = 0; - private String principalIdFieldName = RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME; - - /** - * Construction - * @param redisManager - */ - public RedisCache(RedisManager redisManager, String prefix, int expire, String principalIdFieldName) { - if (redisManager == null) { - throw new IllegalArgumentException("redisManager cannot be null."); - } - this.redisManager = redisManager; - if (prefix != null && !"".equals(prefix)) { - this.keyPrefix = prefix; - } - if (expire != -1) { - this.expire = expire; - } - if (principalIdFieldName != null && !"".equals(principalIdFieldName)) { - this.principalIdFieldName = principalIdFieldName; - } - } - - @Override - public V get(K key) throws CacheException { - logger.debug("get key [{}]",key); - - if (key == null) { - return null; - } - - try { - String redisCacheKey = getRedisCacheKey(key); - Object rawValue = redisManager.get(redisCacheKey); - if (rawValue == null) { - return null; - } - V value = (V) rawValue; - return value; - } catch (Exception e) { - throw new CacheException(e); - } - } - - @Override - public V put(K key, V value) throws CacheException { - logger.debug("put key [{}]",key); - if (key == null) { - logger.warn("Saving a null key is meaningless, return value directly without call Redis."); - return value; - } - try { - String redisCacheKey = getRedisCacheKey(key); - redisManager.set(redisCacheKey, value != null ? value : null, expire); - return value; - } catch (Exception e) { - throw new CacheException(e); - } - } - - @Override - public V remove(K key) throws CacheException { - logger.debug("remove key [{}]",key); - if (key == null) { - return null; - } - try { - String redisCacheKey = getRedisCacheKey(key); - Object rawValue = redisManager.get(redisCacheKey); - V previous = (V) rawValue; - redisManager.del(redisCacheKey); - return previous; - } catch (Exception e) { - throw new CacheException(e); - } - } - - private String getRedisCacheKey(K key) { - if (key == null) { - return null; - } - return this.keyPrefix + getStringRedisKey(key); - } - - private String getStringRedisKey(K key) { - String redisKey; - if (key instanceof PrincipalCollection) { - redisKey = getRedisKeyFromPrincipalIdField((PrincipalCollection) key); - } else { - redisKey = key.toString(); - } - return redisKey; - } - - private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) { - String redisKey; - Object principalObject = key.getPrimaryPrincipal(); - Method pincipalIdGetter = null; - Method[] methods = principalObject.getClass().getDeclaredMethods(); - for (Method m:methods) { - if (RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME.equals(this.principalIdFieldName) - && ("getAuthCacheKey".equals(m.getName()) || "getId".equals(m.getName()))) { - pincipalIdGetter = m; - break; - } - if (m.getName().equals("get" + this.principalIdFieldName.substring(0, 1).toUpperCase() + this.principalIdFieldName.substring(1))) { - pincipalIdGetter = m; - break; - } - } - if (pincipalIdGetter == null) { - throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName); - } - - try { - Object idObj = pincipalIdGetter.invoke(principalObject); - if (idObj == null) { - throw new PrincipalIdNullException(principalObject.getClass(), this.principalIdFieldName); - } - redisKey = idObj.toString(); - } catch (IllegalAccessException e) { - throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName, e); - } catch (InvocationTargetException e) { - throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName, e); - } - - return redisKey; - } - - - @Override - public void clear() throws CacheException { - logger.debug("clear cache"); - Set keys = null; - try { - keys = redisManager.scan(this.keyPrefix + "*"); - } catch (Exception e) { - logger.error("get keys error", e); - } - if (keys == null || keys.size() == 0) { - return; - } - for (String key: keys) { - redisManager.del(key); - } - } - - @Override - public int size() { - Long longSize = 0L; - try { - longSize = new Long(redisManager.scanSize(this.keyPrefix + "*")); - } catch (Exception e) { - logger.error("get keys error", e); - } - return longSize.intValue(); - } - - @SuppressWarnings("unchecked") - @Override - public Set keys() { - Set keys = null; - try { - keys = redisManager.scan(this.keyPrefix + "*"); - } catch (Exception e) { - logger.error("get keys error", e); - return Collections.emptySet(); - } - - if (CollectionUtils.isEmpty(keys)) { - return Collections.emptySet(); - } - - Set convertedKeys = new HashSet(); - for (String key:keys) { - try { - convertedKeys.add((K) key); - } catch (Exception e) { - logger.error("deserialize keys error", e); - } - } - return convertedKeys; - } - - @Override - public Collection values() { - Set keys = null; - try { - keys = redisManager.scan(this.keyPrefix + "*"); - } catch (Exception e) { - logger.error("get values error", e); - return Collections.emptySet(); - } - - if (CollectionUtils.isEmpty(keys)) { - return Collections.emptySet(); - } - - List values = new ArrayList(keys.size()); - for (String key : keys) { - V value = null; - try { - value = (V) redisManager.get(key); - } catch (Exception e) { - logger.error("deserialize values= error", e); - } - if (value != null) { - values.add(value); - } - } - return Collections.unmodifiableList(values); - } - - public String getKeyPrefix() { - return keyPrefix; - } - - public void setKeyPrefix(String keyPrefix) { - this.keyPrefix = keyPrefix; - } - - public String getPrincipalIdFieldName() { - return principalIdFieldName; - } - - public void setPrincipalIdFieldName(String principalIdFieldName) { - this.principalIdFieldName = principalIdFieldName; - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisCacheManager.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisCacheManager.java deleted file mode 100644 index 203d7b6..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisCacheManager.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.opsli.core.security.shiro.cache; - -import org.apache.shiro.cache.Cache; -import org.apache.shiro.cache.CacheException; -import org.apache.shiro.cache.CacheManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @description: 参考 shiro-redis 开源项目 Git地址 https://github.com/alexxiyang/shiro-redis - */ -public class RedisCacheManager implements CacheManager { - - private final Logger logger = LoggerFactory.getLogger(RedisCacheManager.class); - - /** - * fast lookup by name map - */ - private final ConcurrentMap caches = new ConcurrentHashMap(); - - private RedisManager redisManager; - - /** - * expire time in seconds - */ - private static final int DEFAULT_EXPIRE = 1800; - private int expire = DEFAULT_EXPIRE; - - /** - * The Redis key prefix for caches - */ - public static final String DEFAULT_CACHE_KEY_PREFIX = "shiro:cache:"; - private String keyPrefix = DEFAULT_CACHE_KEY_PREFIX; - - public static final String DEFAULT_PRINCIPAL_ID_FIELD_NAME = "authCacheKey or id"; - private String principalIdFieldName = DEFAULT_PRINCIPAL_ID_FIELD_NAME; - - @Override - public Cache getCache(String name) throws CacheException { - logger.debug("get cache, name={}",name); - - Cache cache = caches.get(name); - - if (cache == null) { - cache = new RedisCache(redisManager,keyPrefix + name + ":", expire, principalIdFieldName); - caches.put(name, cache); - } - return cache; - } - - public RedisManager getRedisManager() { - return redisManager; - } - - public void setRedisManager(RedisManager redisManager) { - this.redisManager = redisManager; - } - - public String getKeyPrefix() { - return keyPrefix; - } - - public void setKeyPrefix(String keyPrefix) { - this.keyPrefix = keyPrefix; - } - - public int getExpire() { - return expire; - } - - public void setExpire(int expire) { - this.expire = expire; - } - - public String getPrincipalIdFieldName() { - return principalIdFieldName; - } - - public void setPrincipalIdFieldName(String principalIdFieldName) { - this.principalIdFieldName = principalIdFieldName; - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisManager.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisManager.java deleted file mode 100644 index 17f4dce..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/RedisManager.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.opsli.core.security.shiro.cache; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.core.Cursor; -import org.springframework.data.redis.core.RedisCallback; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ScanOptions; -import org.springframework.util.CollectionUtils; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -/** - * - * @author sunzhiqiang - * 基于spring和redis的redisTemplate工具类 - */ -public class RedisManager { - - @Autowired - private RedisTemplate redisTemplate; - - //=============================common============================ - /** - * 指定缓存失效时间 - * @param key 键 - * @param time 时间(秒) - */ - public void expire(String key,long time){ - redisTemplate.expire(key, time, TimeUnit.SECONDS); - } - - /** - * 判断key是否存在 - * @param key 键 - * @return true 存在 false不存在 - */ - public Boolean hasKey(String key){ - return redisTemplate.hasKey(key); - } - - /** - * 删除缓存 - * @param key 可以传一个值 或多个 - */ - @SuppressWarnings("unchecked") - public void del(String ... key){ - if(key!=null&&key.length>0){ - if(key.length==1){ - redisTemplate.delete(key[0]); - }else{ - redisTemplate.delete(CollectionUtils.arrayToList(key)); - } - } - } - - /** - * 批量删除key - * @param keys - */ - public void del(Collection keys){ - redisTemplate.delete(keys); - } - - //============================String============================= - /** - * 普通缓存获取 - * @param key 键 - * @return 值 - */ - public Object get(String key){ - return redisTemplate.opsForValue().get(key); - } - - /** - * 普通缓存放入 - * @param key 键 - * @param value 值 - */ - public void set(String key,Object value) { - redisTemplate.opsForValue().set(key, value); - } - - /** - * 普通缓存放入并设置时间 - * @param key 键 - * @param value 值 - * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 - */ - public void set(String key,Object value,long time){ - if(time>0){ - redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); - }else{ - set(key, value); - } - } - - /** - * 使用scan命令 查询某些前缀的key - * @param key - * @return - */ - public Set scan(String key){ - Set execute = this.redisTemplate.execute(new RedisCallback>() { - - @Override - public Set doInRedis(RedisConnection connection) throws DataAccessException { - - Set binaryKeys = new HashSet<>(); - - Cursor cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(key).count(1000).build()); - while (cursor.hasNext()) { - binaryKeys.add(new String(cursor.next())); - } - return binaryKeys; - } - }); - return execute; - } - - /** - * 使用scan命令 查询某些前缀的key 有多少个 - * 用来获取当前session数量,也就是在线用户 - * @param key - * @return - */ - public Long scanSize(String key){ - long dbSize = this.redisTemplate.execute(new RedisCallback() { - - @Override - public Long doInRedis(RedisConnection connection) throws DataAccessException { - long count = 0L; - Cursor cursor = connection.scan(ScanOptions.scanOptions().match(key).count(1000).build()); - while (cursor.hasNext()) { - cursor.next(); - count++; - } - return count; - } - }); - return dbSize; - } -} \ No newline at end of file diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/serializer/SerializeUtils.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/serializer/SerializeUtils.java deleted file mode 100644 index 1f51de3..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/cache/serializer/SerializeUtils.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.opsli.core.security.shiro.cache.serializer; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.data.redis.serializer.SerializationException; - -import java.io.*; - -/** - *

序列化工具类

- * - * @author sunzhiqiang23 - * @date 2020-04-27 19:48 - */ -public class SerializeUtils implements RedisSerializer { - - private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class); - - public static boolean isEmpty(byte[] data) { - return (data == null || data.length == 0); - } - - /** - * 序列化 - * @param object - * @return - * @throws SerializationException - */ - @Override - public byte[] serialize(Object object) throws SerializationException { - byte[] result = null; - - if (object == null) { - return new byte[0]; - } - try ( - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream) - ){ - - if (!(object instanceof Serializable)) { - throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " + - "but received an object of type [" + object.getClass().getName() + "]"); - } - - objectOutputStream.writeObject(object); - objectOutputStream.flush(); - result = byteStream.toByteArray(); - } catch (Exception ex) { - logger.error("Failed to serialize",ex); - } - return result; - } - - /** - * 反序列化 - * @param bytes - * @return - * @throws SerializationException - */ - @Override - public Object deserialize(byte[] bytes) throws SerializationException { - - Object result = null; - - if (isEmpty(bytes)) { - return null; - } - - try ( - ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes); - ObjectInputStream objectInputStream = new ObjectInputStream(byteStream) - ){ - result = objectInputStream.readObject(); - } catch (Exception e) { - logger.error("Failed to deserialize",e); - } - return result; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/exception/PrincipalIdNullException.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/exception/PrincipalIdNullException.java deleted file mode 100644 index 2459e80..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/exception/PrincipalIdNullException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.opsli.core.security.shiro.exception; - -public class PrincipalIdNullException extends RuntimeException { - - private static final String MESSAGE = "Principal Id shouldn't be null!"; - - public PrincipalIdNullException(Class clazz, String idMethodName) { - super(clazz + " id field: " + idMethodName + ", value is null\n" + MESSAGE); - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/exception/PrincipalInstanceException.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/exception/PrincipalInstanceException.java deleted file mode 100644 index 443c938..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/exception/PrincipalInstanceException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.opsli.core.security.shiro.exception; - -public class PrincipalInstanceException extends RuntimeException { - - private static final String MESSAGE = "We need a field to identify this Cache Object in Redis. " - + "So you need to defined an id field which you can get unique id to identify this principal. " - + "For example, if you use UserInfo as Principal class, the id field maybe userId, userName, email, etc. " - + "For example, getUserId(), getUserName(), getEmail(), etc.\n" - + "Default value is \"id\", that means your principal object has a method called \"getId()\""; - - public PrincipalInstanceException(Class clazz, String idMethodName) { - super(clazz + " must has getter for field: " + idMethodName + "\n" + MESSAGE); - } - - public PrincipalInstanceException(Class clazz, String idMethodName, Exception e) { - super(clazz + " must has getter for field: " + idMethodName + "\n" + MESSAGE, e); - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/filter/CustomShiroFilter.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/filter/CustomShiroFilter.java deleted file mode 100644 index 5b885f3..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/filter/CustomShiroFilter.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.opsli.core.security.shiro.filter; - - -import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.web.filter.authc.AuthenticatingFilter; -import org.opsli.api.base.result.ResultVo; -import org.opsli.common.constants.SignConstants; -import org.opsli.common.constants.TokenTypeConstants; -import org.opsli.core.msg.TokenMsg; -import org.opsli.core.security.shiro.token.ExternalToken; -import org.opsli.core.security.shiro.token.JwtToken; -import org.opsli.core.utils.JwtUtil; -import org.opsli.core.utils.UserTokenUtil; -import org.springframework.web.bind.annotation.RequestMethod; - -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * oauth2过滤器 - * - * 就是因为,以前单机,页面的挑转自己能控制,失败的时候定一个错误码:401, - * - * 集中登录,集中授权, - * - * @author 孙志强 - - * @date 2017-05-20 13:00 - */ -public class CustomShiroFilter extends AuthenticatingFilter { - - @Override - protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { - //获取请求token - String token = UserTokenUtil.getRequestToken((HttpServletRequest) request); - - if(StringUtils.isBlank(token)){ - return null; - } - - String tokenType = ""; - // 分析token - try { - tokenType = JwtUtil.getClaim(token, SignConstants.TYPE); - }catch (Exception ignored){} - - // 手机登录 - if(TokenTypeConstants.TYPE_EXTERNAL.equals(tokenType)){ - return new ExternalToken(token); - } - // .... 追加登录方式 - - return new JwtToken(token); - } - - @Override - protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { - if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){ - return true; - } - // remeberMe ,remeberMe特殊页面,需要授权, - - return false; - } - - @Override - protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { - HttpServletRequest httpServletRequest = (HttpServletRequest) request; - //获取请求token,如果token不存在,直接返回401 - String token = UserTokenUtil.getRequestToken((HttpServletRequest) request); - if(StringUtils.isBlank(token)){ - HttpServletResponse httpResponse = (HttpServletResponse) response; - httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); - httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); - httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin")); - httpResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); - httpResponse.setContentType("application/json; charset=utf-8"); - // 401 Token失效,请重新登录 - ResultVo error = ResultVo.error(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY.getCode(), - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY.getMessage()); - httpResponse.getWriter().print(error.toJsonStr()); - return false; - } - - return executeLogin(request, response); - } - - @Override - protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { - HttpServletRequest httpServletRequest = (HttpServletRequest) request; - HttpServletResponse httpResponse = (HttpServletResponse) response; - httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); - httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin")); - httpResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); - httpResponse.setContentType("application/json; charset=utf-8"); - - try { - //处理登录失败的异常 - Throwable throwable = e.getCause() == null ? e : e.getCause(); - ResultVo error = ResultVo.error(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY.getCode(), - throwable.getMessage()); - httpResponse.getWriter().print(error.toJsonStr()); - } catch (IOException ignored) {} - return false; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/FlagRealm.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/FlagRealm.java deleted file mode 100644 index 2b728ba..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/FlagRealm.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.opsli.core.security.shiro.realm; - -/** - * Realm 识别类 勿删 - * - * @author Parker - * @date 2020-09-16 - */ -public interface FlagRealm { -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/JwtRealm.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/JwtRealm.java deleted file mode 100644 index 0d955b4..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/JwtRealm.java +++ /dev/null @@ -1,182 +0,0 @@ -package org.opsli.core.security.shiro.realm; - -import cn.hutool.core.collection.CollUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.SimpleAuthenticationInfo; -import org.apache.shiro.authz.AuthorizationInfo; -import org.apache.shiro.authz.SimpleAuthorizationInfo; -import org.apache.shiro.realm.AuthorizingRealm; -import org.apache.shiro.subject.PrincipalCollection; -import org.opsli.api.wrapper.system.tenant.TenantModel; -import org.opsli.api.wrapper.system.user.UserModel; -import org.opsli.common.enums.DictType; -import org.opsli.common.exception.TokenException; -import org.opsli.core.holder.UserContextHolder; -import org.opsli.core.msg.TokenMsg; -import org.opsli.core.security.shiro.token.JwtToken; -import org.opsli.core.utils.TenantUtil; -import org.opsli.core.utils.UserTokenUtil; -import org.opsli.core.utils.UserUtil; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * 认证 - * - * @author Parker - * @date 2020-09-16 - */ -@Component -@Slf4j -public class JwtRealm extends AuthorizingRealm implements FlagRealm { - - - @Override - public boolean supports(AuthenticationToken token) { - return token instanceof JwtToken; - } - - /** - * 授权(验证权限时调用) - */ - @Override - protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { - SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); - - UserModel user = (UserModel) principals.getPrimaryPrincipal(); - String userId = user.getId(); - - //用户权限列表 - List permsSet = UserUtil.getUserAllPermsByUserId(userId); - if(CollUtil.isNotEmpty(permsSet)){ - info.addStringPermissions(permsSet); - } - - //用户角色列表 - List rolesSet = UserUtil.getUserRolesByUserId(userId); - if(CollUtil.isNotEmpty(rolesSet)){ - info.addRoles(rolesSet); - } - - return info; - } - - /** - * 认证(登录时调用) - */ - @Override - protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) - throws AuthenticationException,TokenException { - - String accessToken = (String) token.getPrincipal(); - - // 1. 校验 token 是否有效 - boolean verify = UserTokenUtil.verify(accessToken); - if(!verify){ - // token失效,请重新登录 - throw new TokenException( - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY); - } - - // 2. 查询 用户信息 - String userId = UserTokenUtil.getUserIdByToken(accessToken); - UserModel user = UserUtil.getUser(userId); - - // 3. 是否存在该用户 - if(user == null){ - // token失效,请重新登录 - throw new TokenException( - TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCKED); - } - - // 4. 如果不是超级管理员 和 租户管理员 - if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername()) && - !TenantUtil.SUPER_ADMIN_TENANT_ID.equals(user.getTenantId()) ){ - // 4.1 账号锁定验证 - if(StringUtils.isEmpty(user.getEnable()) || - DictType.NO_YES_NO.getValue().equals(user.getEnable())){ - // 账号已被锁定,请联系管理员 - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCKED); - } - - // 4.2 租户启用验证 - TenantModel tenant = TenantUtil.getTenant(user.getTenantId()); - if(tenant == null){ - // 租户未启用,请联系管理员 - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_TENANT_NOT_USABLE); - } - } - - return new SimpleAuthenticationInfo(user, accessToken, getName()); - } - - - /** - * Token 认证 - */ - public static void authToken() - throws TokenException { - - String accessToken = UserContextHolder.getToken().orElseThrow(() -> new TokenException( - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY)); - - // 1. 校验 token 是否有效 - boolean verify = UserTokenUtil.verify(accessToken); - if(!verify){ - // token失效,请重新登录 - throw new TokenException( - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY); - } - - // 2. 查询 用户信息 - String userId = UserTokenUtil.getUserIdByToken(accessToken); - UserModel user = UserUtil.getUser(userId); - - // 3. 校验账户是否启用 否 - if(user == null || DictType.NO_YES_NO.getValue().equals(user.getEnable())){ - // 账号已被锁定,请联系管理员 - // token失效,请重新登录 - throw new TokenException( - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY); - } - } - - /** - * 按钮权限 认证 - */ - public static void authPerms(String[] currPerms) - throws TokenException { - if(currPerms == null ){ - return; - } - - String accessToken = UserContextHolder.getToken().orElseThrow(() -> new TokenException( - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY)); - - // 查询 用户信息 - String userId = UserTokenUtil.getUserIdByToken(accessToken); - - //用户权限列表 - List permsSet = UserUtil.getUserAllPermsByUserId(userId); - - if(CollUtil.isEmpty(permsSet)){ - // 无权访问该方法 - throw new TokenException( - TokenMsg.EXCEPTION_NOT_AUTH); - } - - for (String currPerm : currPerms) { - if(!permsSet.contains(currPerm)){ - // 无权访问该方法 - throw new TokenException( - TokenMsg.EXCEPTION_NOT_AUTH); - } - } - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/TelRealm.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/TelRealm.java deleted file mode 100644 index b037450..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/realm/TelRealm.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.opsli.core.security.shiro.realm; - -import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authz.AuthorizationInfo; -import org.apache.shiro.realm.AuthorizingRealm; -import org.apache.shiro.subject.PrincipalCollection; -import org.opsli.common.exception.TokenException; -import org.opsli.core.security.shiro.token.ExternalToken; -import org.springframework.stereotype.Component; - - -/** - * 手机登录 认证 - * - * @author Parker - * @date 2020-09-16 - */ -@Component -@Slf4j -public class TelRealm extends AuthorizingRealm implements FlagRealm { - - /** 账号锁定状态 */ - public static final char LOCK_VAL = '1'; - - @Override - public boolean supports(AuthenticationToken token) { - return token instanceof ExternalToken; - } - - /** - * 授权(验证权限时调用) - */ - @Override - protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { - // TODO 待处理 - - return null; - } - - /** - * 对外认证(登录时调用) - */ - @Override - protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) - throws AuthenticationException, TokenException { - // TODO 待处理 - - return null; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/MySessionListener.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/MySessionListener.java deleted file mode 100644 index 367a3ea..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/MySessionListener.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.opsli.core.security.shiro.session; - -import org.apache.shiro.session.Session; -import org.apache.shiro.session.SessionListener; - -/** - *

- * - * @author sunzhiqiang23 - * @date 2020-04-25 17:29 - */ -public class MySessionListener implements SessionListener { - - @Override - public void onStart(Session session) { - System.out.println("会话创建:" + session.getId()); - } - - @Override - public void onStop(Session session) { - System.out.println("会话退出:" + session.getId()); - } - - @Override - public void onExpiration(Session session) { - System.out.println("会话过期:" + session.getId()); - - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/SessionInMemory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/SessionInMemory.java deleted file mode 100644 index 55c344d..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/SessionInMemory.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.opsli.core.security.shiro.session; - -import org.apache.shiro.session.Session; - -import java.util.Date; - -/** - *

- * - * @author sunzhiqiang23 - * @date 2020-04-27 20:52 - */ -public class SessionInMemory { - private Session session; - private Date createTime; - - public Session getSession() { - return session; - } - - public void setSession(Session session) { - this.session = session; - } - - public Date getCreateTime() { - return createTime; - } - - public void setCreateTime(Date createTime) { - this.createTime = createTime; - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/ShiroSession.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/ShiroSession.java deleted file mode 100644 index 9aed8a5..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/ShiroSession.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.opsli.core.security.shiro.session; - -import org.apache.shiro.session.mgt.SimpleSession; - -import java.io.Serializable; -import java.util.Date; - -/** - *

- * - * @author sunzhiqiang23 - * @date 2020-04-27 20:38 - */ - -import java.util.Map; - -/** - * @author: sunzhiqiang - * @date: 2020-04-27 20:38 - * @description: 由于SimpleSession lastAccessTime更改后也会调用SessionDao update方法, - * 增加标识位,如果只是更新lastAccessTime SessionDao update方法直接返回 - */ -public class ShiroSession extends SimpleSession implements Serializable { - // 除lastAccessTime以外其他字段发生改变时为true - private boolean isChanged = false; - - public ShiroSession() { - super(); - this.setChanged(true); - } - - public ShiroSession(String host) { - super(host); - this.setChanged(true); - } - - - @Override - public void setId(Serializable id) { - super.setId(id); - this.setChanged(true); - } - - @Override - public void setStopTimestamp(Date stopTimestamp) { - super.setStopTimestamp(stopTimestamp); - this.setChanged(true); - } - - @Override - public void setExpired(boolean expired) { - super.setExpired(expired); - this.setChanged(true); - } - - @Override - public void setTimeout(long timeout) { - super.setTimeout(timeout); - this.setChanged(true); - } - - @Override - public void setHost(String host) { - super.setHost(host); - this.setChanged(true); - } - - @Override - public void setAttributes(Map attributes) { - super.setAttributes(attributes); - this.setChanged(true); - } - - @Override - public void setAttribute(Object key, Object value) { - super.setAttribute(key, value); - this.setChanged(true); - } - - @Override - public Object removeAttribute(Object key) { - this.setChanged(true); - return super.removeAttribute(key); - } - - /** - * 停止 - */ - @Override - public void stop() { - super.stop(); - this.setChanged(true); - } - - /** - * 设置过期 - */ - @Override - protected void expire() { - this.stop(); - this.setExpired(true); - } - - public boolean isChanged() { - return isChanged; - } - - public void setChanged(boolean isChanged) { - this.isChanged = isChanged; - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj); - } - - @Override - protected boolean onEquals(SimpleSession ss) { - return super.onEquals(ss); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public String toString() { - return super.toString(); - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/ShiroSessionManager.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/ShiroSessionManager.java deleted file mode 100644 index 5bf9663..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/session/ShiroSessionManager.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.opsli.core.security.shiro.session; - - -import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.session.Session; -import org.apache.shiro.session.UnknownSessionException; -import org.apache.shiro.session.mgt.SessionKey; -import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; -import org.apache.shiro.web.session.mgt.WebSessionKey; - -import javax.servlet.ServletRequest; -import java.io.Serializable; - -/** - *

解决单次请求需要多次访问redis

- * - * @author sunzhiqiang23 - * @date 2020-04-27 20:58 - */ -@Slf4j -public class ShiroSessionManager extends DefaultWebSessionManager { - - /** - * 获取session - * 优化单次请求需要多次访问redis的问题 - * @param sessionKey - * @return - * @throws UnknownSessionException - */ - @Override - protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException { - Serializable sessionId = getSessionId(sessionKey); - - ServletRequest request = null; - if (sessionKey instanceof WebSessionKey) { - request = ((WebSessionKey) sessionKey).getServletRequest(); - } - - if (request != null && null != sessionId) { - Object sessionObj = request.getAttribute(sessionId.toString()); - if (sessionObj != null) { - log.debug("read session from request"); - return (Session) sessionObj; - } - } - - Session session = super.retrieveSession(sessionKey); - if (request != null && null != sessionId) { - request.setAttribute(sessionId.toString(), session); - } - return session; - } -} \ No newline at end of file diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/token/ExternalToken.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/token/ExternalToken.java deleted file mode 100644 index ac4694d..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/token/ExternalToken.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opsli.core.security.shiro.token; - - -import org.apache.shiro.authc.AuthenticationToken; - -/** - * 第三方对外接口 token - * - * @author Parker - * @date 2017-05-20 13:22 - */ -public class ExternalToken implements AuthenticationToken { - - private final String token; - - public ExternalToken(String token){ - this.token = token; - } - - @Override - public String getPrincipal() { - return token; - } - - @Override - public Object getCredentials() { - return token; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/token/JwtToken.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/token/JwtToken.java deleted file mode 100644 index 3087384..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/token/JwtToken.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opsli.core.security.shiro.token; - - -import org.apache.shiro.authc.AuthenticationToken; - -/** - * OAuth2 token - * - * @author Parker - * @date 2017-05-20 13:22 - */ -public class JwtToken implements AuthenticationToken { - - private final String token; - - public JwtToken(String token){ - this.token = token; - } - - @Override - public String getPrincipal() { - return token; - } - - @Override - public Object getCredentials() { - return token; - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/utils/ShiroUtils.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/utils/ShiroUtils.java deleted file mode 100644 index 8a85cdf..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/security/shiro/utils/ShiroUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright 2018 人人开源 http://www.renren.io - *

- * 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.security.shiro.utils; - -import org.apache.shiro.SecurityUtils; -import org.apache.shiro.crypto.hash.SimpleHash; -import org.apache.shiro.session.Session; -import org.apache.shiro.subject.Subject; -import org.opsli.api.wrapper.system.user.UserModel; - -/** - * Shiro工具类 - * - * @author 孙志强 - - * @date 2016年11月12日 上午9:49:19 - */ -public class ShiroUtils { - - /** 加密算法 */ - public final static String HASH_ALGORITHM_NAME = "MD5"; - /** 循环次数 */ - public final static int HASH_ITERATIONS = 1; - - public static String sha256(String password, String salt) { - return new SimpleHash(HASH_ALGORITHM_NAME, password, salt, HASH_ITERATIONS).toString(); - } - - public static Session getSession() { - return SecurityUtils.getSubject().getSession(); - } - - public static Subject getSubject() { - return SecurityUtils.getSubject(); - } - - public static UserModel getUser() { - return (UserModel) SecurityUtils.getSubject().getPrincipal(); - } - - public static String getUserId() { - return getUser().getId(); - } - - public static void setSessionAttribute(Object key, Object value) { - getSession().setAttribute(key, value); - } - - public static Object getSessionAttribute(Object key) { - return getSession().getAttribute(key); - } - - public static boolean isLogin() { - return SecurityUtils.getSubject().getPrincipal() != null; - } - - public static void logout() { - SecurityUtils.getSubject().logout(); - } - - public static String getKaptcha(String key) throws RuntimeException { - Object kaptcha = getSessionAttribute(key); - if(kaptcha == null){ - throw new RuntimeException("验证码已失效"); - } - getSession().removeAttribute(key); - return kaptcha.toString(); - } - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/thread/LogsThreadPool.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/thread/LogsThreadPool.java index 1589653..94cc4b4 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/thread/LogsThreadPool.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/thread/LogsThreadPool.java @@ -1,7 +1,7 @@ package org.opsli.core.thread; import lombok.extern.slf4j.Slf4j; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.logs.LogsApi; import org.opsli.api.wrapper.system.logs.LogsModel; import org.opsli.common.thread.AsyncProcessExecutor; @@ -35,8 +35,8 @@ public class LogsThreadPool { AsyncProcessExecutor normalExecutor = AsyncProcessExecutorFactory.createNormalExecutor(); normalExecutor.put(()->{ // 存储临时 token - ResultVo ret = logsApi.insert(logsModel); - if(!ret.isSuccess()){ + ResultWrapper ret = logsApi.insert(logsModel); + if(!ResultWrapper.isSuccess(ret)){ log.error(ret.getMsg()); } }); diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoUtil.java new file mode 100644 index 0000000..c1e67d6 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoUtil.java @@ -0,0 +1,85 @@ +/** + * 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.utils; + +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.opsli.core.options.CryptoConfigFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; + +/** + * 登陆加解密 工具类 + * + * @author Parker + * @date 2022-07-25 6:06 PM + **/ +@Component +@Order(UTIL_ORDER) +@Lazy(false) +public class CryptoUtil { + + /** 获得非对称加解密 执行器 */ + private static CryptoAsymmetricService ASYMMETRIC; + /** 非对称加解密模型 */ + private static CryptoAsymmetric ASYMMETRIC_CRYPTO_MODEL; + /** 获得对称加解密 执行器 */ + private static CryptoSymmetricService SYMMETRIC; + /** 对称加解密模型 */ + private static CryptoSymmetric SYMMETRIC_CRYPTO_MODEL; + + + /** + * 非对称 解密数据 + * @param encryptData 秘文 + * @return 解密厚后Obj + */ + public static Object asymmetricDecryptToObj(String encryptData){ + return ASYMMETRIC.decryptToObj( + ASYMMETRIC_CRYPTO_MODEL, encryptData); + } + + /** + * 对称 加密数据 + * @param data 数据 + * @return 秘文 + */ + public static String symmetricEncryptToStr(Object data){ + return SYMMETRIC.encrypt( + SYMMETRIC_CRYPTO_MODEL, data); + } + + + @Autowired + public void init(OptionsUtil optionsUtil){ + // 非对称 + ASYMMETRIC = CryptoPlugin.getAsymmetric(); + ASYMMETRIC_CRYPTO_MODEL = CryptoConfigFactory.INSTANCE.getCryptoAsymmetric(); + // 对称 + SYMMETRIC = CryptoPlugin.getSymmetric(); + SYMMETRIC_CRYPTO_MODEL = SYMMETRIC.createNilModel(); + SYMMETRIC_CRYPTO_MODEL.setCryptoType(CryptoSymmetricType.DES); + SYMMETRIC_CRYPTO_MODEL.setPrivateKey(ASYMMETRIC_CRYPTO_MODEL.getPublicKey()); + } +} 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 704f1ed..099599d 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 @@ -21,7 +21,7 @@ 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.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.dict.DictDetailApi; import org.opsli.api.wrapper.system.dict.DictDetailModel; import org.opsli.api.wrapper.system.dict.DictWrapper; @@ -77,8 +77,8 @@ public class DictUtil { Object cache = SecurityCache.hGet(redisTemplate, cacheKey, dictValue, (k) -> { // 查询数据库 并保存到缓存内 - ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if (!resultVo.isSuccess()) { + ResultWrapper> resultVo = dictDetailApi.findListByTypeCode(typeCode); + if (!ResultWrapper.isSuccess(resultVo)) { return null; } @@ -117,8 +117,8 @@ public class DictUtil { Object cache = SecurityCache.hGet(redisTemplate, cacheKey, dictName, (k) -> { // 查询数据库 并保存到缓存内 - ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if (!resultVo.isSuccess()) { + ResultWrapper> resultVo = dictDetailApi.findListByTypeCode(typeCode); + if (!ResultWrapper.isSuccess(resultVo)) { return null; } @@ -154,8 +154,8 @@ public class DictUtil { Map dictCacheMap = SecurityCache.hGetAll(redisTemplate, cacheKey, (k) -> { // 查询数据库 并保存到缓存内 - ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if (!resultVo.isSuccess()) { + ResultWrapper> resultVo = dictDetailApi.findListByTypeCode(typeCode); + if (!ResultWrapper.isSuccess(resultVo)) { return null; } @@ -243,7 +243,7 @@ public class DictUtil { String cacheKeyByName = CacheUtil.formatKey( RedisConstants.PREFIX_DICT_NAME + typeCode); - return SecurityCache.removeMore(redisTemplate, cacheKeyByValue, cacheKeyByName); + return SecurityCache.remove(redisTemplate, cacheKeyByValue, cacheKeyByName); } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/EnjoyUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/EnjoyUtil.java new file mode 100644 index 0000000..ee57580 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/EnjoyUtil.java @@ -0,0 +1,90 @@ +/** + * 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.utils; + +import cn.hutool.core.io.IoUtil; +import com.google.common.collect.Maps; +import com.jfinal.kit.Kv; +import com.jfinal.template.Engine; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/*** + * Enjoy 模板引擎 + * + * @author parker + * @date 2020-11-18 13:21 + */ +@Slf4j +public final class EnjoyUtil { + + private static final String BASE_PATH = "/ftl"; + + /** 模板文件Map */ + private static final Map TEMPLATE_FILE_MAP = Maps.newConcurrentMap(); + + /** + * 根据具体魔板生成文件 + * @param templateFileName 模板文件名称 + * @param kv 渲染参数 + * @return String + */ + public static String render(final String templateFileName, Kv kv) { + + // 模板缓存 减少每次更新 + String templateFile = TEMPLATE_FILE_MAP.get(templateFileName); + if(StringUtils.isEmpty(templateFile)){ + + // 如果为空 则IO 读取原始文件 + ClassPathResource resource = new ClassPathResource(BASE_PATH + templateFileName); + try (InputStream inputStream = resource.getInputStream()){ + templateFile = IoUtil.read(inputStream, StandardCharsets.UTF_8); + TEMPLATE_FILE_MAP.put(templateFileName, templateFile); + } catch (Exception e) { + log.error("load file {} error", templateFileName, e); + } + } + + return Engine.use() + // 开启预热模式 + .setDevMode(true) + .getTemplateByString(templateFile) + .renderToString(kv); + } + + /** + * 根据具体魔板生成文件 + * @param template 模板 + * @param kv 渲染参数 + * @return String + */ + public static String renderByStr(final String template, Kv kv) { + + return Engine.use() + // 开启预热模式 + .setDevMode(true) + .getTemplateByString(template) + .renderToString(kv); + } + + + private EnjoyUtil(){} +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/JWTBizUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/JWTBizUtil.java new file mode 100644 index 0000000..e1d5ad0 --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/JWTBizUtil.java @@ -0,0 +1,318 @@ +/** + * 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.utils; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.exceptions.ValidateException; +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTPayload; +import cn.hutool.jwt.JWTValidator; +import cn.hutool.jwt.signers.JWTSigner; +import cn.hutool.jwt.signers.JWTSignerUtil; +import org.opsli.core.base.dto.LoginUserDto; +import org.opsli.plugins.security.JwtConstants; + +import java.util.Date; +import java.util.Map; + +/** + * JWT 的工具类:包含了创建和解码的工具 + * + * @author Parker + * @date 2021年12月22日20:01:23 + */ +public final class JWTBizUtil { + + /** + * 刷新 Token + * + * @param userInfo 用户信息 + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + public static String generateRefreshToken(LoginUserDto userInfo, String secret, Integer expireMinutes) { + Map payloadsMap = BeanUtil.beanToMap(userInfo); + payloadsMap.put(JwtConstants.JWT_CLAIM_TAG, Tag.REFRESH_TOKEN.getTag()); + + // 生成新Token + return generate(payloadsMap, secret, expireMinutes); + } + + /** + * 认证 Token + * + * @param refreshToken 刷新Token + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + public static String generateAccessToken(String refreshToken, String secret, Integer expireMinutes) { + // 验证 刷新Token 是否失效 + verify(refreshToken, secret); + + // 获得 载荷数据 + LoginUserDto loginUserFromToken = getLoginUserFromToken(refreshToken); + Map payloadsMap = BeanUtil.beanToMap(loginUserFromToken); + payloadsMap.put(JwtConstants.JWT_CLAIM_TAG, Tag.TOKEN.getTag()); + + // 生成新Token + return generate(payloadsMap, secret, expireMinutes); + } + + /** + * 认证 Token + * + * @param userInfo 用户信息 + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + public static String generateAccessToken(LoginUserDto userInfo, String secret, Integer expireMinutes) { + Map payloadsMap = BeanUtil.beanToMap(userInfo); + payloadsMap.put(JwtConstants.JWT_CLAIM_TAG, Tag.TOKEN.getTag()); + + // 生成新Token + return generate(payloadsMap, secret, expireMinutes); + } + + + /** + * 生成Token + * + * @param payloadsMap 载荷数据 + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + private static String generate(Map payloadsMap, String secret, Integer expireMinutes) { + byte[] keys = Base64.encode(secret).getBytes(); + JWTSigner jwtSigner = JWTSignerUtil.hs256(keys); + + // 签发时间 + Date issuedAt = DateUtil.date(); + + return JWT.create() + // 载荷数据 + .addPayloads(payloadsMap) + // 签发时间 + .setIssuedAt(DateUtil.offsetMinute(issuedAt, JwtConstants.JWT_SIGNATURE_DELAY)) + // 过期时间 + .setExpiresAt(DateUtil.offsetMinute(issuedAt, expireMinutes)) + // 签名 + .sign(jwtSigner); + } + + + /** + * 校验Token 是否正确 + * + * @param token Token + * @param secret 盐 + */ + public static void verify(String token, String secret) { + byte[] keys = Base64.encode(secret).getBytes(); + JWTSigner jwtSigner = JWTSignerUtil.hs256(keys); + + JWTValidator validator = JWTValidator.of(token); + try { + // 验证签名 + validator.validateAlgorithm(jwtSigner); + } catch (Exception e) { + throw new ValidateException(100524, "Token无效,请重新登录"); + } + + try { + // 验证时间 + validator.validateDate(); + } catch (Exception e) { + throw new ValidateException(100525, "Token已过期,请重新登录", e); + } + } + + /** + * 校验Token 是否正确 (只验证签名) + * + * @param token Token + * @param secret 盐 + */ + public static void verifyBySign(String token, String secret) { + byte[] keys = Base64.encode(secret).getBytes(); + JWTSigner jwtSigner = JWTSignerUtil.hs256(keys); + + JWTValidator validator = JWTValidator.of(token); + try { + // 验证签名 + validator.validateAlgorithm(jwtSigner); + } catch (Exception e) { + throw new ValidateException(100524, "Token无效,请重新登录"); + } + } + + + /** + * 获得登陆用户信息 + * + * @param token Token + */ + public static LoginUserDto getLoginUserFromToken(String token) { + JSONObject payloads = JWT.of(token) + .getPayloads(); + // 移除标识 + payloads.remove(JwtConstants.JWT_CLAIM_TAG); + return payloads.toBean(LoginUserDto.class); + } + + /** + * 获得登陆用户信息 字符串 + * + * @param token Token + */ + public static String getLoginUserStrFromToken(String token) { + JSONObject payloads = JWT.of(token) + .getPayloads(); + // 移除标识 + payloads.remove(JwtConstants.JWT_CLAIM_TAG); + return payloads.toString(); + } + + /** + * 获得Token的签名时间 + * + * @param token Token + */ + public static Date getIssuedDateFromToken(String token) { + // 获得失效时间 + return JWT.of(token).getPayload() + .getClaimsJson().getDate(JWTPayload.ISSUED_AT); + } + + /** + * 获得Token的失效时间 + * + * @param token Token + */ + public static Date getExpiredDateFromToken(String token) { + // 获得失效时间 + return JWT.of(token).getPayload() + .getClaimsJson().getDate(JWTPayload.EXPIRES_AT); + } + + /** + * 判断是否是刷新Token + * + * @param token Token + */ + public static boolean isRefreshToken(String token) { + String tag = Tag.TOKEN.getTag(); + try { + tag = JWT.of(token).getPayload() + .getClaimsJson().getStr(JwtConstants.JWT_CLAIM_TAG); + } catch (Exception ignored) { + } + return Tag.REFRESH_TOKEN.getTag().equals(tag); + } + + /** + * 标签 + */ + private enum Tag { + + /** + * 刷新Token + */ + REFRESH_TOKEN("0"), + /** + * 认证Token + */ + TOKEN("1"); + + private final String tag; + + Tag(String tag) { + this.tag = tag; + } + + public String getTag() { + return tag; + } + } + + + /** + * 私有化构造函数 + */ + private JWTBizUtil() {} + + + public static void main(String[] args) { + String secret = "8128212"; + + LoginUserDto LoginUserDto = new LoginUserDto(); + LoginUserDto.setLoginIp("127.0.0.1"); + LoginUserDto.setMobile("18888888888"); + LoginUserDto.setEmail("meet.parker@foxmail.com"); + LoginUserDto.setUsername("u_111111"); + LoginUserDto.setNickname("Parker"); + LoginUserDto.setUid("12321321L"); + + // 刷新Token 一个月失效 + String refreshToken = JWTBizUtil.generateRefreshToken(LoginUserDto, secret, 43200); + // 认证Token 两小时失效 + String fastToken = JWTBizUtil.generateAccessToken(refreshToken, secret, 120); + // 认证Token 十年失效 + String slowToken = JWTBizUtil.generateAccessToken(refreshToken, secret, 5256000); +// for (int i = 0; i < 100; i++) { +// long l = System.currentTimeMillis(); +// token = JwtUtil.generate(LoginUserDto, secret, 3); +// System.out.println("普通Token耗时:" + (System.currentTimeMillis() - l)); +// } + + System.out.println("刷新Token 一个月失效"); + System.out.println(JwtConstants.TOKEN_HEAD + refreshToken); + System.out.println(""); + System.out.println("认证Token 两小时失效"); + System.out.println(JwtConstants.TOKEN_HEAD + fastToken); + System.out.println(""); + System.out.println("认证Token 十年失效"); + System.out.println(JwtConstants.TOKEN_HEAD + slowToken); + System.out.println(""); + + + LoginUserDto loginUserByToken = JWTBizUtil.getLoginUserFromToken(refreshToken); + System.out.println(JSONUtil.toJsonStr(loginUserByToken)); + + Date date = JWTBizUtil.getExpiredDateFromToken(refreshToken); + System.out.println(DateUtil.formatDateTime(date)); + + // 刷新Token +// for (int i = 0; i < 100; i++) { +// long l = System.currentTimeMillis(); +// token = JWTUtil.refresh(refreshToken, secret, 3); +// System.out.println("刷新Token耗时:" + (System.currentTimeMillis() - l)); +// } + + + ThreadUtil.sleep(2000); + JWTBizUtil.verify(refreshToken, secret); + } + +} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/JwtUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/JwtUtil.java deleted file mode 100644 index 7b22b56..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/JwtUtil.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.opsli.core.utils; - -import cn.hutool.core.codec.Base64; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; -import com.auth0.jwt.JWT; -import com.auth0.jwt.JWTCreator; -import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTDecodeException; -import com.auth0.jwt.interfaces.DecodedJWT; -import lombok.extern.slf4j.Slf4j; -import org.opsli.core.autoconfigure.properties.GlobalProperties; -import org.opsli.common.constants.SignConstants; -import org.opsli.common.constants.TokenTypeConstants; -import org.opsli.common.exception.JwtException; -import org.opsli.core.msg.CoreMsg; -import org.opsli.core.msg.JwtMsg; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.util.Date; - -import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; - -/** - * JWT工具类 - * - * @author 孙志强 - * @date 2020/05/29 21:23 - */ -@Slf4j -@Order(UTIL_ORDER) -@Lazy(false) -@Component -public class JwtUtil { - - /** - * 过期时间改为从配置文件获取 120 分钟 两小时 - */ - public static int EXPIRE_MILLISECOND; - - /** - * JWT认证加密私钥(Base64加密) - */ - private static String ENCRYPT_JWT_INITIAL_SECRET; - - /** 增加初始状态开关 防止异常使用 */ - private static boolean IS_INIT; - - /** - * 校验验证帐号加JWT私钥解密 是否正确 - * @param token Token - * @return boolean 是否正确 - */ - public static boolean verify(String token) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - String secret = getClaim(token, SignConstants.ACCOUNT) + Base64.decodeStr(ENCRYPT_JWT_INITIAL_SECRET); - Algorithm algorithm = Algorithm.HMAC256(secret); - JWTVerifier verifier = JWT.require(algorithm).build(); - verifier.verify(token); - return true; - } - - /** - * 获得Token中的信息 - * @param token token - * @param claim 字段 - * @return java.lang.String - */ - public static String getClaim(String token, String claim) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - try { - DecodedJWT jwt = JWT.decode(token); - return jwt.getClaim(claim).asString(); - } catch (JWTDecodeException e) { - // 解密异常 - String msg = StrUtil.format(JwtMsg.EXCEPTION_DECODE.getMessage(), e.getMessage()); - throw new JwtException(JwtMsg.EXCEPTION_DECODE.getCode(), msg); - } - } - - /** - * 生成签名 - * @param tokenType token类型 - * @param account 帐号 - * @param userId 用户ID - * @param isExpire 是否过期 - * @return java.lang.String 返回加密的Token - */ - public static String sign(String tokenType, String account, - String userId, String tenantId, boolean isExpire) { - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - // 时间戳 - long currentTimeMillis = System.currentTimeMillis(); - // 帐号加JWT私钥加密 - String secret = account + Base64.decodeStr(ENCRYPT_JWT_INITIAL_SECRET); - Algorithm algorithm = Algorithm.HMAC256(secret); - JWTCreator.Builder builder = JWT.create() - .withClaim(SignConstants.TYPE, tokenType) - .withClaim(SignConstants.ACCOUNT, account) - .withClaim(SignConstants.USER_ID, userId) - .withClaim(SignConstants.TENANT_ID, tenantId) - .withClaim(SignConstants.TIMESTAMP, String.valueOf(currentTimeMillis)); - - // 如果为是 则开启失效时间 - if(isExpire){ - // 时间偏移,取最终失效时间 - Date expireDate = DateUtil.offsetMillisecond(DateUtil.date(currentTimeMillis), EXPIRE_MILLISECOND); - // token 过期时间 - builder.withExpiresAt(expireDate); - } - - // 附带account帐号信息 - return builder.sign(algorithm); - } - - - // ================== - - /** - * 初始化 - */ - @Autowired - public void init(GlobalProperties globalProperties){ - if(globalProperties != null && globalProperties.getAuth() != null - && globalProperties.getAuth().getToken() != null - ){ - // 获得 Token失效时间 - JwtUtil.EXPIRE_MILLISECOND = globalProperties.getAuth() - .getToken().getEffectiveTime() * 60 * 1000; - - // 获得 Token初始盐值 - JwtUtil.ENCRYPT_JWT_INITIAL_SECRET = globalProperties.getAuth() - .getToken().getSecret(); - } - - IS_INIT = true; - } - - // ================== - - public static void main(String[] args) { - String token = JwtUtil.sign(TokenTypeConstants.TYPE_SYSTEM, - "test","123123", "",true); - - boolean verify = JwtUtil.verify(token); - System.out.println(token); - System.out.println(verify); - } -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/LogUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/LogUtil.java deleted file mode 100644 index a23cd62..0000000 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/LogUtil.java +++ /dev/null @@ -1,231 +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.utils; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; -import cn.hutool.json.JSONUtil; -import com.google.common.collect.Lists; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.reflect.MethodSignature; -import org.opsli.api.wrapper.system.logs.LogsModel; -import org.opsli.api.wrapper.system.menu.MenuModel; -import org.opsli.api.wrapper.system.user.UserModel; -import org.opsli.api.wrapper.system.user.UserOrgRefModel; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; -import org.opsli.common.utils.IPUtil; -import org.opsli.core.thread.LogsThreadPool; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.Method; -import java.util.List; - -/** - * 日志工具类 - * - * @author Parker - * @date 2020-09-22 11:17 - */ -@Slf4j -public final class LogUtil { - - /** - * 保存日志 - * @param point point - * @param e 异常 - * @param timerCount 花费毫秒数 - */ - public static void saveLog(ProceedingJoinPoint point, Exception e, long timerCount){ - - try { - Object[] args = point.getArgs(); - MethodSignature signature = (MethodSignature) point.getSignature(); - Method method = signature.getMethod(); - - RequestAttributes ra = RequestContextHolder.getRequestAttributes(); - ServletRequestAttributes sra = (ServletRequestAttributes) ra; - if(sra == null){ - return; - } - HttpServletRequest request = sra.getRequest(); - - // EnableLog 如果不被 EnableLog修饰 则直接退出 - // 判断 方法上是否使用 HotData注解 如果没有表示开启热数据 则直接跳过 - EnableLog enableLog = method.getAnnotation(EnableLog.class); - if(enableLog == null){ - return; - } - - UserModel user; - try { - user = UserUtil.getUser(); - }catch (Exception ex){ - return; - } - - String argsStr = null; - try { - argsStr = JSONUtil.toJsonStr(args); - }catch (Exception ignored){} - - LogsModel logsModel = new LogsModel(); - // 操作方法 - String methodName = request.getMethod(); - // 获得IP - String clientIpAddress = IPUtil.getClientIdBySingle(request); - - // 设置标题 - setTitle(point, method, logsModel, user); - // 设置类型 - logsModel.setType(e == null ? LogsModel.TYPE_ACCESS : LogsModel.TYPE_EXCEPTION); - // 设置客户端代理 - logsModel.setUserAgent(request.getHeader("user-agent")); - // 设置URI - logsModel.setRequestUri(request.getRequestURI()); - // 设置IP - logsModel.setRemoteAddr(clientIpAddress); - // 设置参数 - logsModel.setParams(argsStr); - // 设置方法 - logsModel.setMethod(methodName); - // 设置执行时长 - logsModel.setTimeout(timerCount); - // 设置异常信息 - if(e != null){ - logsModel.setException(e.getMessage()); - } - - logsModel.setCreateBy(user.getId()); - logsModel.setUpdateBy(user.getId()); - logsModel.setIzManual(true); - - // 如果组织IDs 为空则进行默认赋值 - UserOrgRefModel userOrgRefModel = UserUtil.getUserDefOrgByUserId(user.getId()); - if(null != userOrgRefModel){ - logsModel.setOrgIds(userOrgRefModel.getOrgIds()); - } - - // 赋值 租户ID - logsModel.setTenantId(user.getTenantId()); - - // 保存日志 - LogsThreadPool.process(logsModel); - } catch (Exception ex){ - log.error(ex.getMessage(), ex); - } - } - - /** - * 设置日志标题 - * @param point point - * @param method 方法 - * @param logsModel 日志模型 - */ - private static void setTitle(ProceedingJoinPoint point, Method method, LogsModel logsModel, UserModel user){ - // 设置 title - EnableLog enableLog = method.getAnnotation(EnableLog.class); - if(enableLog != null){ - //注解上的描述,操作日志内容 - String title = enableLog.title(); - if(StringUtils.isNotEmpty(title)){ - logsModel.setTitle(title); - } - } - // 如果title 还为空 则系统自动赋值 - if(StringUtils.isEmpty(logsModel.getTitle())){ - RequiresPermissions permissions = method.getAnnotation(RequiresPermissions.class); - RequiresPermissionsCus permissionsCus = method.getAnnotation(RequiresPermissionsCus.class); - - List values = null; - if(permissions != null){ - values = Convert.toList(String.class, permissions.value()); - }else if(permissionsCus != null){ - values = Convert.toList(String.class, permissionsCus.value()); - } - - if(CollUtil.isNotEmpty(values)){ - if(values != null && values.size() > 0){ - String perms = values.get(0); - // 获得当前用户所持有菜单 - List menuListByUserId = UserUtil.getMenuListByUserId(user.getId()); - if(menuListByUserId != null){ - // 根据当前controller权限 获得对应权限数据 - MenuModel permsModel = MenuUtil.getMenuByPermissions(perms); - if(permsModel != null){ - // 依次获得菜单全名 - StringBuilder logTitleBuf = new StringBuilder(); - List parentMenu = getParentMenu(menuListByUserId, permsModel); - for (int i = parentMenu.size() - 1; i >= 0; i--) { - logTitleBuf.append(parentMenu.get(i).getMenuName()) - .append("-"); - } - String logTitle = logTitleBuf.toString(); - if(StringUtils.isNotEmpty(logTitle)){ - logsModel.setTitle(logTitle + permsModel.getMenuName()); - } - } - } - } - } - - // 如果title 还是为空 则系统自动赋class - if(StringUtils.isEmpty(logsModel.getTitle())){ - // 获取请求的类名 - String className = point.getTarget().getClass().getName(); - String methodName = method.getName(); - logsModel.setTitle(className+"."+methodName); - } - } - } - - - /** - * 递归 获得菜单全名 - * @param menuList 菜单集合 - * @param permsModel 权限模型 - * @return List - */ - private static List getParentMenu(List menuList, MenuModel permsModel){ - List menuModels = Lists.newArrayList(); - MenuModel parentMenu = null; - for (MenuModel menu : menuList) { - if(menu.getId().equals(permsModel.getParentId())){ - parentMenu = menu; - break; - } - } - - if(parentMenu != null){ - menuModels.add(parentMenu); - List temp = getParentMenu(menuList, parentMenu); - menuModels.addAll(temp); - } - - return menuModels; - } - - - // ================= - - private LogUtil(){} -} 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 b6bc8f9..2644fc7 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 @@ -18,7 +18,7 @@ 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.base.result.ResultWrapper; import org.opsli.api.web.system.menu.MenuApi; import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.common.constants.RedisConstants; @@ -69,8 +69,8 @@ public class MenuUtil { Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = menuApi.getByPermissions(permissions); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = menuApi.getByPermissions(permissions); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); 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 96bb2d0..918078b 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 @@ -23,7 +23,7 @@ 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.base.result.ResultWrapper; import org.opsli.api.web.system.options.OptionsApi; import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.common.annotation.OptionDict; @@ -143,8 +143,8 @@ public class OptionsUtil { Object cache = SecurityCache.hGet(redisTemplate, cacheKey, optionCode, (k) -> { // 查询数据库 - ResultVo resultVo = optionsApi.getByCode(optionCode); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = optionsApi.getByCode(optionCode); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); 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 f76fad2..cdef447 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 @@ -18,7 +18,7 @@ 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.base.result.ResultWrapper; import org.opsli.api.web.system.tenant.TenantApi; import org.opsli.api.wrapper.system.tenant.TenantModel; import org.opsli.core.cache.CacheUtil; @@ -74,8 +74,8 @@ public class TenantUtil { Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = tenantApi.getTenantByUsable(tenantId); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = tenantApi.getTenantByUsable(tenantId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } 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 1542240..4f5d982 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 @@ -16,8 +16,6 @@ package org.opsli.core.utils; import cn.hutool.core.convert.Convert; -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; @@ -26,20 +24,25 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; 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; import org.opsli.common.enums.LoginLimitRefuse; +import org.opsli.common.enums.LoginModelType; import org.opsli.common.exception.TokenException; import org.opsli.core.autoconfigure.properties.GlobalProperties; +import org.opsli.core.base.dto.LoginUserDto; import org.opsli.core.cache.CacheUtil; import org.opsli.core.holder.UserContextHolder; import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.TokenMsg; import org.opsli.plugins.redis.RedisPlugin; +import org.opsli.plugins.security.JwtConstants; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; @@ -47,6 +50,7 @@ import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.util.Date; +import java.util.Optional; import java.util.concurrent.TimeUnit; import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @@ -64,11 +68,12 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; public class UserTokenUtil { /** token 缓存名 */ - public static final String TOKEN_NAME = TokenConstants.ACCESS_TOKEN; + public static final String TOKEN_NAME = JwtConstants.TOKEN_HEADER; /** 限制登录数量 -1 为无限大 */ public static final int ACCOUNT_LIMIT_INFINITE = -1; /** 登录配置信息 */ public static GlobalProperties.Auth.Login LOGIN_PROPERTIES; + public static GlobalProperties.Auth.Token TOKEN_PROPERTIES; /** Redis插件 */ private static RedisPlugin redisPlugin; /** 增加初始状态开关 防止异常使用 */ @@ -76,85 +81,75 @@ public class UserTokenUtil { /** * 根据 user 创建Token - * @param user 用户 - * @return UserTokenUtil.TokenRet + * @param loginUser 用户 + * @return String */ - public static ResultVo createToken(UserModel user) { + public static String createAccessToken(LoginUserDto loginUser) { // 判断 工具类是否初始化完成 ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - if (user == null) { - // 生成Token失败 - throw new TokenException(TokenMsg.EXCEPTION_TOKEN_CREATE_ERROR); + // 2022-07-22 用户票据新增 终端缓存 多终端下不影响 + String ticketSetKey = CacheUtil.formatKey( + RedisConstants.PREFIX_TICKET + + loginUser.getLoginFrom() + ":" + loginUser.getUsername()); + + GlobalProperties.Auth.Login loginProperties = UserTokenUtil.LOGIN_PROPERTIES; + // 如果当前登录开启 数量限制 + if(loginProperties.getLimitCount() > ACCOUNT_LIMIT_INFINITE){ + // 当前用户已存在 Token数量 + Long ticketLen = redisPlugin.sSize(ticketSetKey); + if(ticketLen !=null && ticketLen >= loginProperties.getLimitCount()){ + // 如果是拒绝后者 则直接抛出异常 + if(LoginLimitRefuse.AFTER == loginProperties.getLimitRefuse()){ + // 生成Token失败 您的账号已在其他设备登录 + throw new TokenException(TokenMsg.EXCEPTION_TOKEN_CREATE_LIMIT_ERROR); + } + // 如果是拒绝前者 则弹出前者 + else { + redisPlugin.sPop(ticketSetKey); + } + } } - try { - // 如果当前登录开启 数量限制 - if(LOGIN_PROPERTIES.getLimitCount() > ACCOUNT_LIMIT_INFINITE){ - // 当前用户已存在 Token数量 - Long ticketLen = redisPlugin.sSize( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername())); - if(ticketLen !=null && ticketLen >= LOGIN_PROPERTIES.getLimitCount()){ - // 如果是拒绝后者 则直接抛出异常 - if(LoginLimitRefuse.AFTER == LOGIN_PROPERTIES.getLimitRefuse()){ - // 生成Token失败 您的账号已在其他设备登录 - throw new TokenException(TokenMsg.EXCEPTION_TOKEN_CREATE_LIMIT_ERROR); - } - // 如果是拒绝前者 则弹出前者 - else { - redisPlugin.sPop( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()) - ); - } - } - } + // 认证Token + String accessToken = JWTBizUtil.generateAccessToken(loginUser, + TOKEN_PROPERTIES.getSecret(), TOKEN_PROPERTIES.getEffectiveTime()); - // 开启续命模式 如果为续命模式 则不指定Token 的 失效时间 - // 生成 Token 包含 username userId timestamp - boolean reviveMode = LOGIN_PROPERTIES.getReviveMode() != null && LOGIN_PROPERTIES.getReviveMode(); - String signToken = JwtUtil.sign( - TokenTypeConstants.TYPE_SYSTEM, - user.getUsername(), - user.getId(), - user.getTenantId(), - !reviveMode); - - // 获得当前Token时间戳 - long timestamp = Convert.toLong( - JwtUtil.getClaim(signToken, SignConstants.TIMESTAMP)); - // 获得失效偏移量时间 - long endTimestamp = DateUtil.offsetMillisecond( - DateUtil.date(timestamp), JwtUtil.EXPIRE_MILLISECOND).getTime(); - - // 在redis存一份 token 是为了防止 人为造假 - // 保存用户token - Long saveLong = redisPlugin.sPut( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()), - signToken - ); - if(saveLong != null && saveLong > 0){ - // 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命 - redisPlugin.expire( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()), - JwtUtil.EXPIRE_MILLISECOND, TimeUnit.MILLISECONDS); - - TokenRet tokenRet = new TokenRet(); - tokenRet.setToken(signToken); - tokenRet.setEndTimestamp(endTimestamp); - - return ResultVo.success(tokenRet); - } + // 获得当前Token时间戳 + Date expiredDateFromToken = JWTBizUtil.getExpiredDateFromToken(accessToken); + + // 在redis存一份 token 是为了防止 人为造假 + // 保存用户token + redisPlugin.sPut(ticketSetKey, accessToken); + // 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命 + redisPlugin.expireAt(ticketSetKey, expiredDateFromToken); + + return accessToken; + } + + /** + * 获得登陆凭证信息 + * @return String + */ + public static Optional getLoginUserDto() { + String token = UserContextHolder.getToken().orElseThrow(() -> new TokenException( + TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY)); + return getLoginUserDto(token); + } - }catch (TokenException te){ - throw te; - }catch (Exception e){ - log.error(e.getMessage() , e); + /** + * 根据 Token 获得登陆凭证信息 + * @return String + */ + public static Optional getLoginUserDto(String token) { + if(StrUtil.isBlank(token)){ + return Optional.empty(); } - // 生成Token失败 - throw new TokenException(TokenMsg.EXCEPTION_TOKEN_CREATE_ERROR); + + LoginUserDto loginUserFromToken = JWTBizUtil.getLoginUserFromToken(token); + return Optional.ofNullable(loginUserFromToken); } /** @@ -178,7 +173,8 @@ public class UserTokenUtil { } String userId = ""; try { - userId = JwtUtil.getClaim(token, SignConstants.USER_ID); + LoginUserDto loginUserFromToken = JWTBizUtil.getLoginUserFromToken(token); + userId = loginUserFromToken.getUid(); }catch (Exception ignored){} return userId; } @@ -204,7 +200,8 @@ public class UserTokenUtil { } String username = ""; try { - username = JwtUtil.getClaim(token, SignConstants.ACCOUNT); + LoginUserDto loginUserFromToken = JWTBizUtil.getLoginUserFromToken(token); + username = loginUserFromToken.getUsername(); }catch (Exception ignored){} return username; } @@ -230,7 +227,8 @@ public class UserTokenUtil { } String username = ""; try { - username = JwtUtil.getClaim(token, SignConstants.TENANT_ID); + LoginUserDto loginUserFromToken = JWTBizUtil.getLoginUserFromToken(token); + username = loginUserFromToken.getTenantId(); }catch (Exception ignored){} return username; } @@ -249,19 +247,22 @@ public class UserTokenUtil { return; } try { + LoginUserDto loginUserDto = getLoginUserDto(token) + .orElseThrow(()-> new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID)); + + // 2022-07-22 用户票据新增 终端缓存 多终端下不影响 + String ticketSetKey = CacheUtil.formatKey( + RedisConstants.PREFIX_TICKET + + loginUserDto.getLoginFrom() + ":" + loginUserDto.getUsername()); + // 获得要退出用户 - String userId = getUserIdByToken(token); - UserModel user = UserUtil.getUser(userId); + UserModel user = UserUtil.getUser(loginUserDto.getUid()); if(user != null){ // 删除Token信息 - redisPlugin.sRemove( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()), - token); + redisPlugin.sRemove(ticketSetKey, token); // 如果缓存中 无该用户任何Token信息 则删除用户缓存 - Long size = redisPlugin.sSize( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()) - ); + Long size = redisPlugin.sSize(ticketSetKey); if(size == null || size == 0L) { // 删除相关信息 UserUtil.refreshUser(user); @@ -269,8 +270,8 @@ public class UserTokenUtil { UserUtil.refreshUserAllPerms(user.getId()); UserUtil.refreshUserMenus(user.getId()); UserUtil.refreshUserOrgs(user.getId()); - UserUtil.refreshUserDefRole(userId); - UserUtil.refreshUserDefOrg(userId); + UserUtil.refreshUserDefRole(user.getId()); + UserUtil.refreshUserDefOrg(user.getId()); } } @@ -281,157 +282,73 @@ public class UserTokenUtil { * 验证 token * @param token token */ - public static boolean verify(String token) { + public static void verify(String token) { // 判断 工具类是否初始化完成 ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); if(StringUtils.isEmpty(token)){ - return false; + throw new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID); } - try { - // 1. 校验是否是有效的 token - boolean tokenVerify = JwtUtil.verify(token); - if(!tokenVerify){ - return false; - } - - // 2. 校验当前缓存中token是否失效 - // 生成MD5 16进制码 用于缩减存储 - // 删除相关信息 - String username = getUserNameByToken(token); - - boolean hashKey = redisPlugin.sHashKey( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + username), - token); - if(!hashKey){ - return false; - } - // 3. 校验通过后 如果开启续命模式 则整体延长登录时效 - if(BooleanUtil.isTrue(LOGIN_PROPERTIES.getReviveMode())){ - // 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命 - redisPlugin.expire( - CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + username), - JwtUtil.EXPIRE_MILLISECOND, TimeUnit.MILLISECONDS); - } - - } catch (Exception e){ - return false; + // 1. 校验是否是有效的 token + // 开启续命模式 如果为续命模式 则不验证失效时间 + boolean reviveMode = LOGIN_PROPERTIES.getReviveMode() != null && LOGIN_PROPERTIES.getReviveMode(); + if(reviveMode){ + JWTBizUtil.verifyBySign(token, TOKEN_PROPERTIES.getSecret()); + }else { + JWTBizUtil.verify(token, TOKEN_PROPERTIES.getSecret()); } - return true; - } - // ============================ 锁账号 操作 - /** - * 验证锁定账号 - * @param username 用户名 - */ - public static void verifyLockAccount(String username){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + LoginUserDto loginUserDto = getLoginUserDto(token) + .orElseThrow(()-> new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID)); + // 2022-07-22 用户票据新增 终端缓存 多终端下不影响 + String ticketSetKey = CacheUtil.formatKey( + RedisConstants.PREFIX_TICKET + + loginUserDto.getLoginFrom() + ":" + loginUserDto.getUsername()); - // 判断账号是否临时锁定 - Long loseTimeMillis = Convert.toLong(redisPlugin.get( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username))); - if(loseTimeMillis != null){ - Date currDate = DateUtil.date(); - DateTime loseDate = DateUtil.date(loseTimeMillis); - // 偏移5分钟 - DateTime currLoseDate = DateUtil.offsetSecond(loseDate, LOGIN_PROPERTIES.getSlipLockSpeed()); - - // 计算失效剩余时间( 分 ) - long betweenM = DateUtil.between(currLoseDate, currDate, DateUnit.MINUTE); - if(betweenM > 0){ - String msg = StrUtil.format(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getMessage() - ,betweenM + "分钟"); - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getCode(), msg); - }else{ - // 计算失效剩余时间( 秒 ) - long betweenS = DateUtil.between(currLoseDate, currDate, DateUnit.SECOND); - String msg = StrUtil.format(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getMessage() - ,betweenS + "秒"); - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getCode(), msg); - } + // 2. 校验当前缓存中token是否失效 + boolean hashKey = redisPlugin.sHashKey(ticketSetKey, token); + if(!hashKey){ + throw new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID); } - } - /** - * 锁定账号 - * @param username 用户名 - */ - public static TokenMsg lockAccount(String username){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - - // 如果失败次数 超过阈值 则锁定账号 - Long slipNum = redisPlugin.increment( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username)); - if (slipNum != null){ - // 设置失效时间为 5分钟 - redisPlugin.expire( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username), - LOGIN_PROPERTIES.getSlipLockSpeed()); - - // 如果确认 都失败 则存入临时缓存 - if(slipNum >= LOGIN_PROPERTIES.getSlipCount()){ - long currentTimeMillis = System.currentTimeMillis(); - // 存入Redis - redisPlugin.put( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username), - currentTimeMillis, LOGIN_PROPERTIES.getSlipLockSpeed()); - } + // 3. 校验通过后 如果开启续命模式 则整体延长登录时效 + if(BooleanUtil.isTrue(LOGIN_PROPERTIES.getReviveMode())){ + // 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命 + redisPlugin.expire(ticketSetKey, + TOKEN_PROPERTIES.getEffectiveTime(), TimeUnit.MILLISECONDS); } - - - return TokenMsg.EXCEPTION_LOGIN_ACCOUNT_NO; } + /** * 获得当前失败次数 - * @param username 用户名 + * @param principal 主键凭证 */ - public static long getSlipCount(String username){ + public static long getSlipCount(String principal){ // 判断 工具类是否初始化完成 ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + // 登陆类型 + LoginModelType loginModelType = LoginModelType.getTypeByStr(principal); - long count = 0L; - Object obj = redisPlugin.get( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username)); + // 获得当前失败次数 + String key = CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + + loginModelType.name().toLowerCase() + ":" + principal); + long slipCount = 0L; + Object obj = redisPlugin.get(key); if(obj != null){ try { - count = Convert.convert(Long.class, obj); + slipCount = Convert.convert(Long.class, obj); }catch (Exception ignored){} } - return count; - } - - - /** - * 清除锁定账号 - * @param username 用户名 - */ - public static void clearLockAccount(String username){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - - // 删除失败次数记录 - redisPlugin.del( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username)); - // 删除失败次数记录 - redisPlugin.del( - CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username)); + return slipCount; } @@ -466,6 +383,8 @@ public class UserTokenUtil { && globalProperties.getAuth().getLogin() != null ){ // 登录配置信息 + UserTokenUtil.TOKEN_PROPERTIES = globalProperties.getAuth().getToken(); + // 登录配置信息 UserTokenUtil.LOGIN_PROPERTIES = globalProperties.getAuth().getLogin(); } @@ -476,20 +395,4 @@ public class UserTokenUtil { } - // ===================== - - @Data - @EqualsAndHashCode(callSuper = false) - public static class TokenRet { - - /** Token */ - @ApiModelProperty(value = "Token") - private String token; - - /** 失效时间戳 */ - @ApiModelProperty(value = "失效时间戳") - private Long endTimestamp; - - } - } 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 a4e1eca..a3dbfae 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 @@ -18,10 +18,11 @@ package org.opsli.core.utils; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.crypto.hash.Md5Hash; -import org.opsli.api.base.result.ResultVo; +//import org.apache.shiro.crypto.hash.Md5Hash; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.user.UserApi; import org.opsli.api.web.system.user.UserOrgRefApi; import org.opsli.api.web.system.user.UserRoleRefApi; @@ -164,6 +165,10 @@ public class UserUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + if(StrUtil.isEmpty(userId)){ + return null; + } + // 缓存Key String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + userId); @@ -175,8 +180,8 @@ public class UserUtil { userModelTemp.setIzApi(true); // 查询数据库 - ResultVo resultVo = userApi.get(userModelTemp); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = userApi.get(userModelTemp); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -207,21 +212,104 @@ public class UserUtil { ThrowExceptionUtil.isThrowException(!IS_INIT, CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + if(StrUtil.isEmpty(userName)){ + return null; + } + // 缓存Key - String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USERNAME + userName); + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_USERNAME + userName); - Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { + String userId = (String) SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = userApi.getUserByUsername(userName); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = userApi.getUserByUsername(userName); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } - return resultVo.getData(); + + if(null == resultVo.getData()){ + return null; + } + + return resultVo.getData().getId(); + }, true); + + // 只查一次 + return getUser(userId, true); + } + + + /** + * 根据 mobile 获得用户 + * @param mobile 手机号 + * @return UserModel + */ + public static UserModel getUserByMobile(String mobile){ + // 判断 工具类是否初始化完成 + ThrowExceptionUtil.isThrowException(!IS_INIT, + CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + + if(StrUtil.isEmpty(mobile)){ + return null; + } + + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_MOBILE + mobile); + + String userId = (String) SecurityCache.get(redisTemplate, cacheKey, (k) -> { + // 查询数据库 + ResultWrapper resultVo = userApi.getUserByMobile(mobile); + if(!ResultWrapper.isSuccess(resultVo)){ + return null; + } + + if(null == resultVo.getData()){ + return null; + } + + return resultVo.getData().getId(); + }, true); + + // 只查一次 + return getUser(userId, true); + } + + + /** + * 根据 email 获得用户 + * @param email 邮箱 + * @return UserModel + */ + public static UserModel getUserByEmail(String email){ + // 判断 工具类是否初始化完成 + ThrowExceptionUtil.isThrowException(!IS_INIT, + CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + + if(StrUtil.isEmpty(email)){ + return null; + } + + // 缓存Key + String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_EMAIL + email); + + String userId = (String) SecurityCache.get(redisTemplate, cacheKey, (k) -> { + // 查询数据库 + ResultWrapper resultVo = userApi.getUserByEmail(email); + if(!ResultWrapper.isSuccess(resultVo)){ + return null; + } + + if(null == resultVo.getData()){ + return null; + } + + return resultVo.getData().getId(); }, true); - return Convert.convert(UserModel.class, cache); + // 只查一次 + return getUser(userId, true); } + /** * 根据 userId 获得用户角色列表 * @param userId 用户ID @@ -245,8 +333,8 @@ public class UserUtil { final String finalUserId = userId; Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userRoleRefApi.getRolesByUserId(finalUserId); - if(!resultVo.isSuccess()){ + ResultWrapper> resultVo = userRoleRefApi.getRolesByUserId(finalUserId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -284,8 +372,8 @@ public class UserUtil { final String finalUserId = userId; Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userRoleRefApi.getAllPerms(finalUserId); - if(!resultVo.isSuccess()){ + ResultWrapper> resultVo = userRoleRefApi.getAllPerms(finalUserId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -322,8 +410,8 @@ public class UserUtil { final String finalUserId = userId; Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userOrgRefApi.findListByUserId(finalUserId); - if(!resultVo.isSuccess()){ + ResultWrapper> resultVo = userOrgRefApi.findListByUserId(finalUserId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -373,8 +461,8 @@ public class UserUtil { final String finalUserId = userId; Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo> resultVo = userRoleRefApi.getMenuListByUserId(finalUserId); - if(!resultVo.isSuccess()){ + ResultWrapper> resultVo = userRoleRefApi.getMenuListByUserId(finalUserId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -412,8 +500,8 @@ public class UserUtil { final String finalUserId = userId; Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = userRoleRefApi.getDefRoleByUserId(finalUserId); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = userRoleRefApi.getDefRoleByUserId(finalUserId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -447,8 +535,8 @@ public class UserUtil { final String finalUserId = userId; Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> { // 查询数据库 - ResultVo resultVo = userOrgRefApi.getDefOrgByUserId(finalUserId); - if(!resultVo.isSuccess()){ + ResultWrapper resultVo = userOrgRefApi.getDefOrgByUserId(finalUserId); + if(!ResultWrapper.isSuccess(resultVo)){ return null; } return resultVo.getData(); @@ -498,10 +586,12 @@ public class UserUtil { } String cacheKeyByUserId = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + user.getId()); - String cacheKeyByUsername = CacheUtil.formatKey(RedisConstants.PREFIX_USERNAME + user.getUsername()); + String cacheKeyByUsername = CacheUtil.formatKey(RedisConstants.PREFIX_USER_USERNAME + user.getUsername()); + String cacheKeyByMobile = CacheUtil.formatKey(RedisConstants.PREFIX_USER_MOBILE + user.getMobile()); + String cacheKeyByEmail = CacheUtil.formatKey(RedisConstants.PREFIX_USER_EMAIL + user.getEmail()); - return SecurityCache.removeMore(redisTemplate, - cacheKeyByUserId, cacheKeyByUsername); + return SecurityCache.remove(redisTemplate, + cacheKeyByUserId, cacheKeyByUsername, cacheKeyByMobile, cacheKeyByEmail); } @@ -666,21 +756,6 @@ public class UserUtil { userAllPermsByUserId.contains(PERMS_TENANT); } - /** - * 处理密码 - * @param password 密码 - * @param secretKey 盐值 - * @return String - */ - public static String handlePassword(String password, String secretKey){ - // 判断 工具类是否初始化完成 - ThrowExceptionUtil.isThrowException(!IS_INIT, - CoreMsg.OTHER_EXCEPTION_UTILS_INIT); - - - return new Md5Hash(password, secretKey).toHex(); - } - // ===================================== /** diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/VerificationCodeUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/VerificationCodeUtil.java new file mode 100644 index 0000000..138de6f --- /dev/null +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/VerificationCodeUtil.java @@ -0,0 +1,297 @@ +/** + * 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.utils; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.opsli.common.constants.RedisConstants; +import org.opsli.common.exception.ServiceException; +import org.opsli.common.utils.UniqueStrGeneratorUtils; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.msg.CoreMsg; +import org.opsli.core.msg.TokenMsg; +import org.opsli.plugins.redis.RedisPlugin; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * 验证码工具类 + * + * @author 周鹏程 + * @date 2022-07-28 5:55 PM + **/ +@Component +public class VerificationCodeUtil { + + /** 5分钟失效 */ + private static final int EXPIRED_MINUTE = 5; + /** 凭证 10分钟失效 */ + private static final int CERTIFICATE_EXPIRED_MINUTE = 10; + + /** 增加初始状态开关 防止异常使用 */ + private static boolean IS_INIT; + private static RedisPlugin redisPlugin; + + + /** + * 创建邮箱验证码 + * @param email 邮箱 + * @return VerificationCodeModel + */ + public static VerificationCodeModel createEmailCode(String email, String type){ + return createCode(RedisConstants.PREFIX_TMP_EMAIL_CODE_NAME, email, type); + } + + /** + * 创建手机验证码 + * @param mobile 手机号 + * @return VerificationCodeModel + */ + public static VerificationCodeModel createMobileCode(String mobile, String type){ + return createCode(RedisConstants.PREFIX_TMP_MOBILE_CODE_NAME, mobile, type); + } + + /** + * 创建验证码 + * @param cacheKey 缓存Key + * @param principal 主键 + * @return VerificationCodeModel + */ + private static VerificationCodeModel createCode(String cacheKey, String principal, String type){ + // 判断 工具类是否初始化完成 + ThrowExceptionUtil.isThrowException(!IS_INIT, + CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + + if(!StrUtil.isAllNotEmpty(principal, type)){ + // 参数异常 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL); + } + + long currentTimeMillis = System.currentTimeMillis(); + + // 缓存Key + String cacheKeyTmp = CacheUtil.formatKey(cacheKey + type + ":" + principal); + + // 判断是否频繁生成 + String valueTmp = (String) redisPlugin.get(cacheKeyTmp); + if(StrUtil.isNotEmpty(valueTmp)){ + String[] split = valueTmp.split("_"); + if(split.length == 2){ + long expiredDateTs = Long.parseLong(split[0]); + // 获取开始时间 + Date createTime = DateUtil.offsetMinute(DateUtil.date(expiredDateTs), -EXPIRED_MINUTE); + // 偏移40秒后时间 + Date offsetTime = DateUtil.offsetSecond(createTime, 30); + // 如果当前时间 小于 偏移后时间 则不可再次生成验证码 + boolean isNotOk = currentTimeMillis < offsetTime.getTime(); + if(isNotOk){ + // 验证码 生成过于频繁 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_OFTEN); + } + } + } + + // 失效时间 + DateTime expiredDate = DateUtil.offsetMinute( + DateUtil.date(currentTimeMillis), EXPIRED_MINUTE); + + String randomNumbers = RandomUtil.randomNumbers(6); + + // 缓存值 + String value = expiredDate.getTime() + "_" + randomNumbers; + + // 相同的 验证码存在 一个 hash中 + redisPlugin.put(cacheKeyTmp, value, EXPIRED_MINUTE, TimeUnit.MINUTES); + + return VerificationCodeModel.builder() + .verificationCode(randomNumbers) + .expiredDate(expiredDate) + .expiredMinute(EXPIRED_MINUTE) + .build(); + } + + + /** + * 验证邮箱验证码(生成凭证) + * @param email 主键 + * @param code 验证码 + * @return certificate + */ + public static String checkEmailCodeToCreateCertificate(String email, String code, String type){ + return checkCode(RedisConstants.PREFIX_TMP_EMAIL_CODE_NAME, email, code, type, true); + } + + /** + * 验证手机验证码(生成凭证) + * @param mobile 主键 + * @param code 验证码 + * @return certificate + */ + public static String checkMobileCodeToCreateCertificate(String mobile, String code, String type){ + return checkCode(RedisConstants.PREFIX_TMP_MOBILE_CODE_NAME, mobile, code, type, true); + } + + /** + * 验证邮箱验证码 + * @param email 主键 + * @param code 验证码 + */ + public static void checkEmailCode(String email, String code, String type){ + checkCode(RedisConstants.PREFIX_TMP_EMAIL_CODE_NAME, email, code, type, false); + } + + /** + * 验证手机验证码 + * @param mobile 主键 + * @param code 验证码 + */ + public static void checkMobileCode(String mobile, String code, String type){ + checkCode(RedisConstants.PREFIX_TMP_MOBILE_CODE_NAME, mobile, code, type, false); + } + + /** + * 验证验证码 + * @param cacheKey 缓存Key + * @param principal 主键 + * @param code 验证码 + * @param type 类型 + * @param isCreateCertificate 是否生成凭证 + * @return certificate + */ + private static String checkCode( + String cacheKey, String principal, String code, String type, boolean isCreateCertificate){ + // 判断 工具类是否初始化完成 + ThrowExceptionUtil.isThrowException(!IS_INIT, + CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + + if(!StrUtil.isAllNotEmpty(principal, code, type)){ + // 参数异常 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL); + } + + long currentTimeMillis = System.currentTimeMillis(); + + // 缓存Key + String cacheKeyTmp = CacheUtil.formatKey(cacheKey + type + ":" + principal); + + // 缓存值 + String value = (String) redisPlugin.get(cacheKeyTmp); + if(StrUtil.isEmpty(value)){ + // 验证码过期 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_NULL); + } + + String[] split = value.split("_"); + if(split.length != 2){ + // 验证码过期 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_NULL); + } + + if(!code.equals(split[1])){ + // 验证码不正确 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ERROR); + } + + long expiredDateTs = Long.parseLong(split[0]); + boolean isExpired = currentTimeMillis > expiredDateTs; + if(isExpired){ + // 验证码过期 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_NULL); + } + + redisPlugin.del(cacheKeyTmp); + + // 判断是否生成凭证 + if(!isCreateCertificate){ + return null; + } + + // 创建唯一数 + // 缓存Key + Long increment = redisPlugin + .increment(CacheUtil.formatKey(RedisConstants.PREFIX_TMP_VERIFICATION_CERTIFICATE_NUM_NAME)); + String certificate = UniqueStrGeneratorUtils.generator(increment); + + // 缓存Key + String certificateCacheKeyTmp = CacheUtil.formatKey( + RedisConstants.PREFIX_TMP_VERIFICATION_CERTIFICATE_NAME + certificate); + redisPlugin.put(certificateCacheKeyTmp, "0", CERTIFICATE_EXPIRED_MINUTE, TimeUnit.MINUTES); + return certificate; + } + + + /** + * 验证验凭证 + * @param type 类型 + * @param certificate 凭证 + */ + public static void checkCertificate(String type, String certificate){ + // 判断 工具类是否初始化完成 + ThrowExceptionUtil.isThrowException(!IS_INIT, + CoreMsg.OTHER_EXCEPTION_UTILS_INIT); + + if(!StrUtil.isAllNotEmpty(type, certificate)){ + // 参数异常 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL); + } + + // 缓存Key + String certificateCacheKeyTmp = CacheUtil.formatKey( + RedisConstants.PREFIX_TMP_VERIFICATION_CERTIFICATE_NAME + certificate); + + Object value = redisPlugin.get(certificateCacheKeyTmp); + if(value == null){ + // 凭证验证失败 + throw new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_CERTIFICATE_ERROR); + } + // 验证后不论成功还是失败 直接删除凭证 + redisPlugin.del(certificateCacheKeyTmp); + } + + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class VerificationCodeModel { + + /** 验证码 */ + private String verificationCode; + + /** 过期时间 */ + private Date expiredDate; + + /** 过期分钟 */ + private Integer expiredMinute; + + } + + @Autowired + public void init(RedisPlugin redisPlugin){ + VerificationCodeUtil.redisPlugin = redisPlugin; + IS_INIT = true; + } + +} diff --git a/opsli-modulars/opsli-modulars-generator/pom.xml b/opsli-modulars/opsli-modulars-generator/pom.xml index c30cb60..e1bbfa5 100644 --- a/opsli-modulars/opsli-modulars-generator/pom.xml +++ b/opsli-modulars/opsli-modulars-generator/pom.xml @@ -15,7 +15,7 @@ com.baomidou mybatis-plus-generator - 3.4.1 + 3.5.2 @@ -24,11 +24,6 @@ 2.3 - - com.jfinal - enjoy - 4.9.06 - diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/api/GenLogsApi.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/api/GenLogsApi.java index 5588dfa..3ce8ac9 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/api/GenLogsApi.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/api/GenLogsApi.java @@ -15,7 +15,7 @@ */ package org.opsli.modulars.generator.logs.api; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.modulars.generator.logs.wrapper.GenLogsModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -45,10 +45,10 @@ public interface GenLogsApi { /** * 生成记录 查一条 * @param tableId 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getByTableId") - ResultVo getByTableId(String tableId); + ResultWrapper getByTableId(String tableId); /** * 代码生成 修改 @@ -61,10 +61,10 @@ public interface GenLogsApi { * * @param menuParentId 上级菜单ID * @param tableId 表ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/createMenu") - ResultVo createMenu(String menuParentId, String tableId); + ResultWrapper createMenu(String menuParentId, String tableId); } diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/service/impl/GenLogsServiceImpl.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/service/impl/GenLogsServiceImpl.java index fb77201..3f02b35 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/service/impl/GenLogsServiceImpl.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/logs/service/impl/GenLogsServiceImpl.java @@ -18,7 +18,7 @@ package org.opsli.modulars.generator.logs.service.impl; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.apache.commons.lang3.StringUtils; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.menu.MenuApi; import org.opsli.api.wrapper.system.menu.MenuFullModel; import org.opsli.common.utils.WrapperUtil; @@ -177,9 +177,9 @@ public class GenLogsServiceImpl extends CrudServiceImpl insertRet = menuApi.saveMenuByFull(menuFullModel); + ResultWrapper insertRet = menuApi.saveMenuByFull(menuFullModel); - return insertRet.isSuccess(); + return ResultWrapper.isSuccess(insertRet); } 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 ccceaec..0da577f 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 @@ -19,18 +19,18 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.beanutils.BeanUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; +import org.springframework.security.access.prepost.PreAuthorize; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; import org.opsli.core.base.controller.BaseRestController; import org.opsli.modulars.generator.logs.api.GenLogsApi; import org.opsli.modulars.generator.logs.entity.GenLogs; import org.opsli.modulars.generator.logs.service.IGenLogsService; import org.opsli.modulars.generator.logs.wrapper.GenLogsModel; import org.opsli.plugins.generator.utils.GeneratorHandleUtil; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -49,22 +49,23 @@ public class GenLogsRestController extends BaseRestController getByTableId(String tableId) { + public ResultWrapper getByTableId(String tableId) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); GenLogsModel byTableId = IService.getByTableId(tableId); - return ResultVo.success(byTableId); + return ResultWrapper.getSuccessResultWrapper(byTableId); } /** * 代码生成 修改 */ @ApiOperation(value = "代码生成", notes = "代码生成") - @RequiresPermissions("dev_generator_create") - @EnableLog + @PreAuthorize("hasAuthority('dev_generator_create')") + @OperateLogger(description = "代码生成", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.INSERT, db = true) @Override public void create(HttpServletRequest request, HttpServletResponse response) { // request 对象属性 @@ -88,13 +89,14 @@ public class GenLogsRestController extends BaseRestController createMenu(String menuParentId, String tableId) { + public ResultWrapper createMenu(String menuParentId, String tableId) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -104,9 +106,9 @@ public class GenLogsRestController extends BaseRestController get(GenTableModel model); + ResultWrapper get(GenTableModel model); /** * 表 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -70,79 +70,79 @@ public interface TableApi { /** * 表 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody GenTableAndColumnModel model); + ResultWrapper insert(@RequestBody GenTableAndColumnModel model); /** * 表 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody GenTableAndColumnModel model); + ResultWrapper update(@RequestBody GenTableAndColumnModel model); /** * 表 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 表 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** * 同步到数据库 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/sync") - ResultVo sync(String id); + ResultWrapper sync(String id); /** * 获得当前数据库 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/getTables") - ResultVo getTables(); + ResultWrapper getTables(); /** * 导入选中表 * * @param tableNames 表名集合 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importTables") - ResultVo importTables(String tableNames); + ResultWrapper importTables(String tableNames); /** * 获得数据库类型下 字段类型 * @return List */ @GetMapping("/getFieldTypes") - ResultVo> getFieldTypes(); + ResultWrapper> getFieldTypes(); /** * 获得数据库类型下 全部类型对应Java类型 * @return List */ @GetMapping("/getJavaFieldTypes") - ResultVo > getJavaFieldTypes(); + ResultWrapper > getJavaFieldTypes(); /** * 获得全部类型对应Java类型集合(兜底String 类型) * @return List */ @GetMapping("/getJavaFieldTypesBySafety") - ResultVo>> getJavaFieldTypesBySafety(); + ResultWrapper>> getJavaFieldTypesBySafety(); } 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 fa43ca3..a6107c4 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 @@ -19,10 +19,13 @@ import cn.hutool.core.convert.Convert; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; +import org.springframework.security.access.prepost.PreAuthorize; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; + import org.opsli.common.exception.ServiceException; import org.opsli.common.utils.WrapperUtil; import org.opsli.core.base.controller.BaseRestController; @@ -68,12 +71,12 @@ public class GenTableRestController extends BaseRestController get(GenTableModel model) { + public ResultWrapper get(GenTableModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -93,7 +96,7 @@ public class GenTableRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -115,19 +118,20 @@ public class GenTableRestController extends BaseRestController insert(GenTableAndColumnModel model) { + public ResultWrapper insert(GenTableAndColumnModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -137,19 +141,20 @@ public class GenTableRestController extends BaseRestController update(GenTableAndColumnModel model) { + public ResultWrapper update(GenTableAndColumnModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -159,20 +164,21 @@ public class GenTableRestController extends BaseRestController del(String id){ + public ResultWrapper del(String id){ // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -186,20 +192,21 @@ public class GenTableRestController extends BaseRestController delAll(String ids){ + public ResultWrapper delAll(String ids){ // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -215,19 +222,20 @@ public class GenTableRestController extends BaseRestController sync(String id){ + public ResultWrapper sync(String id){ // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -239,7 +247,7 @@ public class GenTableRestController extends BaseRestController columnModelList = iGenTableColumnService. @@ -250,24 +258,25 @@ public class GenTableRestController extends BaseRestController getTables() { + public ResultWrapper getTables() { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - return ResultVo.success(ImportTableUtil.findTables()); + return ResultWrapper.getSuccessResultWrapper(ImportTableUtil.findTables()); } @ApiOperation(value = "导入数据库表", notes = "导入数据库表") - @RequiresPermissions("dev_generator_import") - @EnableLog + @PreAuthorize("hasAuthority('dev_generator_import')") + @OperateLogger(description = "导入数据库表", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importTables(String tableNames) { + public ResultWrapper importTables(String tableNames) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -277,36 +286,36 @@ public class GenTableRestController extends BaseRestController> getFieldTypes() { + public ResultWrapper> getFieldTypes() { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - return ResultVo.success(ImportTableUtil.getFieldTypes()); + return ResultWrapper.getSuccessResultWrapper(ImportTableUtil.getFieldTypes()); } @ApiOperation(value = "获得数据库类型下 全部类型对应Java类型", notes = "获得数据库类型下 全部类型对应Java类型") @Override - public ResultVo> getJavaFieldTypes() { + public ResultWrapper> getJavaFieldTypes() { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - return ResultVo.success(ImportTableUtil.getJavaFieldTypes()); + return ResultWrapper.getSuccessResultWrapper(ImportTableUtil.getJavaFieldTypes()); } @ApiOperation(value = "获得全部类型对应Java类型集合(兜底String 类型)", notes = "获得全部类型对应Java类型集合(兜底String 类型)") @Override - public ResultVo>> getJavaFieldTypesBySafety() { + public ResultWrapper>> getJavaFieldTypesBySafety() { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - return ResultVo.success(ImportTableUtil.getJavaFieldTypesBySafety()); + return ResultWrapper.getSuccessResultWrapper(ImportTableUtil.getJavaFieldTypesBySafety()); } } diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateDetailRestApi.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateDetailRestApi.java index ab72bd4..ba4a542 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateDetailRestApi.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateDetailRestApi.java @@ -17,12 +17,9 @@ package org.opsli.modulars.generator.template.api; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.modulars.generator.template.wrapper.GenTemplateDetailModel; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -37,7 +34,7 @@ import java.util.List; * * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的 * - * @author 周鹏程 + * @author Parker * @date 2021-05-28 17:12:38 */ public interface GenTemplateDetailRestApi { @@ -50,20 +47,20 @@ public interface GenTemplateDetailRestApi { /** * 代码模板详情 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(GenTemplateDetailModel model); + ResultWrapper get(GenTemplateDetailModel model); /** * 代码模板详情 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -72,73 +69,72 @@ public interface GenTemplateDetailRestApi { /** * 代码模板详情 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody GenTemplateDetailModel model); + ResultWrapper insert(@RequestBody GenTemplateDetailModel model); /** * 代码模板详情 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody GenTemplateDetailModel model); + ResultWrapper update(@RequestBody GenTemplateDetailModel model); /** * 代码模板详情 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** * 代码模板详情 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/delAll") - ResultVo delAll(String ids); + ResultWrapper delAll(String ids); /** - * 代码模板详情 Excel 导出 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + * 代码模板详情 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 代码模板详情 Excel 导出 + * + * @param certificate 凭证 + * @param response response + */ + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 代码模板详情 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 代码模板详情 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper importExcel(MultipartHttpServletRequest request); /** * 代码模板详情 Excel 下载导入模版 * @param parentId parentId - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findListByParentId") - ResultVo> findListByParentId(String parentId); + ResultWrapper> findListByParentId(String parentId); } diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateRestApi.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateRestApi.java index 039fd1c..c49ec54 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateRestApi.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/api/GenTemplateRestApi.java @@ -17,14 +17,11 @@ package org.opsli.modulars.generator.template.api; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.modulars.generator.template.wrapper.GenTemplateAndDetailModel; import org.opsli.modulars.generator.template.wrapper.GenTemplateCopyModel; import org.opsli.modulars.generator.template.wrapper.GenTemplateModel; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -39,7 +36,7 @@ import javax.servlet.http.HttpServletResponse; * * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的 * - * @author 周鹏程 + * @author Parker * @date 2021-05-27 14:33:49 */ public interface GenTemplateRestApi { @@ -52,20 +49,20 @@ public interface GenTemplateRestApi { /** * 代码模板 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/get") - ResultVo get(GenTemplateModel model); + ResultWrapper get(GenTemplateModel model); /** * 代码模板 查询分页 * @param pageNo 当前页 * @param pageSize 每页条数 * @param request request - * @return ResultVo + * @return ResultWrapper */ @GetMapping("/findPage") - ResultVo findPage( + ResultWrapper findPage( @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request @@ -74,80 +71,79 @@ public interface GenTemplateRestApi { /** * 代码模板 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insert") - ResultVo insert(@RequestBody GenTemplateModel model); + ResultWrapper insert(@RequestBody GenTemplateModel model); /** * 代码模板 新增 和 明细 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/insertAndDetail") - ResultVo insertAndDetail(@RequestBody GenTemplateAndDetailModel model); + ResultWrapper insertAndDetail(@RequestBody GenTemplateAndDetailModel model); /** * 代码模板 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/update") - ResultVo update(@RequestBody GenTemplateModel model); + ResultWrapper update(@RequestBody GenTemplateModel model); /** * 代码模板 修改 和 明细 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/updateAndDetail") - ResultVo updateAndDetail(@RequestBody GenTemplateAndDetailModel model); + ResultWrapper updateAndDetail(@RequestBody GenTemplateAndDetailModel model); /** * 复制 代码模板 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/copy") - ResultVo copy(@RequestBody GenTemplateCopyModel model); + ResultWrapper copy(@RequestBody GenTemplateCopyModel model); /** * 代码模板 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/del") - ResultVo del(String id); + ResultWrapper del(String id); /** - * 代码模板 Excel 导出 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); + * 代码模板 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @GetMapping("/excel/auth/{type}") + ResultWrapper exportExcelAuth( + @PathVariable("type") String type, + HttpServletRequest request); + + /** + * 代码模板 Excel 导出 + * + * @param certificate 凭证 + * @param response response + */ + @GetMapping("/excel/export/{certificate}") + void exportExcel( + @PathVariable("certificate") String certificate, + HttpServletResponse response); /** * 代码模板 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 代码模板 Excel 下载导入模版 - * @param response response - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); + ResultWrapper importExcel(MultipartHttpServletRequest request); } diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplate.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplate.java index 6b9cfb8..196dbf6 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplate.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplate.java @@ -32,7 +32,7 @@ import org.opsli.core.base.entity.BaseEntity; /** * 代码模板 Entity * - * @author 周鹏程 + * @author Parker * @date 2021-05-27 14:33:49 */ @Data diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplateDetail.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplateDetail.java index b0198b8..f4d5b09 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplateDetail.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/entity/GenTemplateDetail.java @@ -32,7 +32,7 @@ import org.opsli.core.base.entity.BaseEntity; /** * 代码模板详情 Entity * - * @author 周鹏程 + * @author Parker * @date 2021-05-28 17:12:38 */ @Data diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateDetailMapper.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateDetailMapper.java index 5762689..9587a89 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateDetailMapper.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateDetailMapper.java @@ -27,7 +27,7 @@ import org.opsli.modulars.generator.template.entity.GenTemplateDetail; /** * 代码模板详情 Mapper * - * @author 周鹏程 + * @author Parker * @date 2021-05-28 17:12:38 */ @Mapper diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateMapper.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateMapper.java index f1999ab..5c94467 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateMapper.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/mapper/GenTemplateMapper.java @@ -27,7 +27,7 @@ import org.opsli.modulars.generator.template.entity.GenTemplate; /** * 代码模板 Mapper * - * @author 周鹏程 + * @author Parker * @date 2021-05-27 14:33:49 */ @Mapper diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateDetailService.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateDetailService.java index 182e472..5c3ad28 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateDetailService.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateDetailService.java @@ -27,7 +27,7 @@ import java.util.List; /** * 代码模板详情 Service * - * @author 周鹏程 + * @author Parker * @date 2021-05-28 17:12:38 */ public interface IGenTemplateDetailService extends CrudServiceInterface { diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateService.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateService.java index 750f951..e0fb514 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateService.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/IGenTemplateService.java @@ -30,7 +30,7 @@ import org.opsli.modulars.generator.template.wrapper.GenTemplateModel; /** * 代码模板 Service * - * @author 周鹏程 + * @author Parker * @date 2021-05-27 14:33:49 */ public interface IGenTemplateService extends CrudServiceInterface { diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateDetailServiceImpl.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateDetailServiceImpl.java index 72f210d..d4bb5a3 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateDetailServiceImpl.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateDetailServiceImpl.java @@ -48,7 +48,7 @@ import java.util.Set; /** * 代码模板详情 Service Impl * - * @author 周鹏程 + * @author Parker * @date 2021-05-28 17:12:38 */ @Service diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateServiceImpl.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateServiceImpl.java index 43382f2..bab912f 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateServiceImpl.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/service/impl/GenTemplateServiceImpl.java @@ -51,7 +51,7 @@ import java.util.List; /** * 代码模板 Service Impl * - * @author 周鹏程 + * @author Parker * @date 2021-05-27 14:33:49 */ @Service @@ -191,7 +191,7 @@ public class GenTemplateServiceImpl extends CrudServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq("table_type", base.getTableType()); queryWrapper.notIn(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID), id); - int count = this.count(queryWrapper); + long count = this.count(queryWrapper); if(count == 0){ // 代码模板同一表类型下,至少保障有一个模板 throw new GeneratorException(GeneratorMsg.EXCEPTION_TEMPLATE_AT_LEAST_ONE); 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 4769735..7d5e885 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 @@ -17,39 +17,39 @@ package org.opsli.modulars.generator.template.web; -import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.convert.Convert; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.opsli.common.annotation.RequiresPermissionsCus; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.web.system.user.UserApi; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.modulars.generator.template.api.GenTemplateDetailRestApi; +import org.opsli.modulars.generator.template.entity.GenTemplateDetail; +import org.opsli.modulars.generator.template.service.IGenTemplateDetailService; import org.opsli.modulars.generator.template.wrapper.GenTemplateDetailModel; import org.opsli.plugins.generator.utils.GenTemplateUtil; import org.opsli.plugins.generator.utils.GeneratorHandleUtil; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; import java.util.List; - - -import org.opsli.modulars.generator.template.entity.GenTemplateDetail; -import org.opsli.modulars.generator.template.service.IGenTemplateDetailService; +import java.util.Optional; /** * 代码模板详情 Controller * - * @author 周鹏程 + * @author Parker * @date 2021-05-28 17:12:38 */ @Api(tags = GenTemplateDetailRestApi.TITLE) @@ -62,17 +62,17 @@ public class GenTemplateDetailRestController extends BaseRestController get(GenTemplateDetailModel model) { + public ResultWrapper get(GenTemplateDetailModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -80,166 +80,160 @@ public class GenTemplateDetailRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 代码模板详情 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增代码模板详情数据", notes = "新增代码模板详情数据") - @RequiresPermissions("generator_template_insert") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_insert')") + @OperateLogger(description = "新增代码模板详情数据", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(GenTemplateDetailModel model) { + public ResultWrapper insert(GenTemplateDetailModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); // 调用新增方法 IService.insert(model); - return ResultVo.success("新增代码模板详情成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增代码模板详情成功"); } /** * 代码模板详情 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改代码模板详情数据", notes = "修改代码模板详情数据") - @RequiresPermissions("generator_template_update") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_update')") + @OperateLogger(description = "修改代码模板详情数据", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(GenTemplateDetailModel model) { + public ResultWrapper update(GenTemplateDetailModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); // 调用修改方法 IService.update(model); - return ResultVo.success("修改代码模板详情成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改代码模板详情成功"); } /** * 代码模板详情 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除代码模板详情数据", notes = "删除代码模板详情数据") - @RequiresPermissions("generator_template_update") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_update')") + @OperateLogger(description = "删除代码模板详情数据", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); IService.delete(id); - return ResultVo.success("删除代码模板详情成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除代码模板详情成功"); } /** * 代码模板详情 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除代码模板详情数据", notes = "批量删除代码模板详情数据") - @RequiresPermissions("generator_template_update") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_update')") + @OperateLogger(description = "批量删除代码模板详情数据", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除代码模板详情成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除代码模板详情成功"); } /** - * 代码模板详情 Excel 导出 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("generator_template_export") - @EnableLog + * 代码模板详情 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('generator_template_export', 'generator_template_import')") @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 判断代码生成器 是否启用 - GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, UserApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } + - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(GenTemplateDetailRestApi.SUB_TITLE, queryBuilder.build(), response, method); + /** + * 代码模板详情 Excel 导出 + * @param response response + */ + @ApiOperation(value = "导出Excel", notes = "导出Excel") + @PreAuthorize("hasAuthority('generator_template_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.SELECT, db = true) + @Override + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } /** * 代码模板详情 Excel 导入 * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("generator_template_import") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_import')") + @OperateLogger(description = "代码模板详情 Excel 导入", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); return super.importExcel(request); } - /** - * 代码模板详情 Excel 下载导入模版 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("generator_template_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 判断代码生成器 是否启用 - GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(GenTemplateDetailRestApi.SUB_TITLE, response, method); - } @Override - public ResultVo> findListByParentId(String parentId) { + public ResultWrapper> findListByParentId(String parentId) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - return ResultVo.success(GenTemplateUtil.getTemplateDetailList(parentId)); + return ResultWrapper + .getSuccessResultWrapper( + GenTemplateUtil.getTemplateDetailList(parentId)); } } 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 08c8699..d77c14f 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 @@ -17,38 +17,38 @@ package org.opsli.modulars.generator.template.web; -import cn.hutool.core.util.ReflectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.opsli.common.annotation.RequiresPermissionsCus; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.web.system.user.UserApi; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.modulars.generator.template.api.GenTemplateRestApi; +import org.opsli.modulars.generator.template.entity.GenTemplate; +import org.opsli.modulars.generator.template.service.IGenTemplateService; import org.opsli.modulars.generator.template.wrapper.GenTemplateAndDetailModel; import org.opsli.modulars.generator.template.wrapper.GenTemplateCopyModel; import org.opsli.modulars.generator.template.wrapper.GenTemplateModel; import org.opsli.plugins.generator.utils.GeneratorHandleUtil; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; - - -import org.opsli.modulars.generator.template.entity.GenTemplate; -import org.opsli.modulars.generator.template.service.IGenTemplateService; +import java.util.Optional; /** * 代码模板 Controller * - * @author 周鹏程 + * @author Parker * @date 2021-05-27 14:33:49 */ @Api(tags = GenTemplateRestApi.TITLE) @@ -61,17 +61,17 @@ public class GenTemplateRestController extends BaseRestController get(GenTemplateModel model) { + public ResultWrapper get(GenTemplateModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -79,33 +79,34 @@ public class GenTemplateRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 代码模板 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增代码模板数据", notes = "新增代码模板数据") - @RequiresPermissions("generator_template_insert") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_insert')") + @OperateLogger(description = "新增代码模板数据", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(GenTemplateModel model) { + public ResultWrapper insert(GenTemplateModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -114,19 +115,20 @@ public class GenTemplateRestController extends BaseRestController insertAndDetail(GenTemplateAndDetailModel model) { + public ResultWrapper insertAndDetail(GenTemplateAndDetailModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -135,19 +137,20 @@ public class GenTemplateRestController extends BaseRestController update(GenTemplateModel model) { + public ResultWrapper update(GenTemplateModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -156,19 +159,20 @@ public class GenTemplateRestController extends BaseRestController updateAndDetail(GenTemplateAndDetailModel model) { + public ResultWrapper updateAndDetail(GenTemplateAndDetailModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -177,37 +181,39 @@ public class GenTemplateRestController extends BaseRestController copy(GenTemplateCopyModel model) { + public ResultWrapper copy(GenTemplateCopyModel model) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); // 调用复制方法 IService.copy(model); - return ResultVo.success("复制代码模板成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("复制代码模板成功"); } /** * 代码模板 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除代码模板数据", notes = "删除代码模板数据") - @RequiresPermissions("generator_template_update") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_update')") + @OperateLogger(description = "删除代码模板数据", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); @@ -215,69 +221,59 @@ public class GenTemplateRestController extends BaseRestController exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, UserApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(GenTemplateRestApi.SUB_TITLE, queryBuilder.build(), response, method); + + /** + * 代码模板 Excel 导出 + * @param response response + */ + @ApiOperation(value = "导出Excel", notes = "导出Excel") + @PreAuthorize("hasAuthority('generator_template_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.SELECT, db = true) + @Override + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } + /** * 代码模板 Excel 导入 * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("generator_template_import") - @EnableLog + @PreAuthorize("hasAuthority('generator_template_import')") + @OperateLogger(description = "代码模板 Excel 导入", + module = ModuleEnum.MODULE_GENERATOR, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { // 判断代码生成器 是否启用 GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); return super.importExcel(request); } - /** - * 代码模板 Excel 下载导入模版 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("generator_template_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 判断代码生成器 是否启用 - GeneratorHandleUtil.judgeGeneratorEnable(super.globalProperties); - - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(GenTemplateRestApi.SUB_TITLE, response, method); - } - } diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateAndDetailModel.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateAndDetailModel.java index ee05223..d7210cb 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateAndDetailModel.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateAndDetailModel.java @@ -32,7 +32,7 @@ import java.util.List; /** * 代码模板 Model * -* @author 周鹏程 +* @author Parker * @date 2021-05-27 14:33:49 */ @Data diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateCopyModel.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateCopyModel.java index 198499a..7ce6194 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateCopyModel.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateCopyModel.java @@ -30,7 +30,7 @@ import org.opsli.plugins.excel.annotation.ExcelInfo; /** * 代码模板 Model * -* @author 周鹏程 +* @author Parker * @date 2021-05-27 14:33:49 */ @Data diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateDetailModel.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateDetailModel.java index 2e60a29..8f993f3 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateDetailModel.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateDetailModel.java @@ -31,7 +31,7 @@ import org.opsli.plugins.excel.annotation.ExcelInfo; /** * 代码模板详情 Model * -* @author 周鹏程 +* @author Parker * @date 2021-05-28 17:12:38 */ @Data diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateModel.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateModel.java index 78b4090..d2e7640 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateModel.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/modulars/generator/template/wrapper/GenTemplateModel.java @@ -30,7 +30,7 @@ import org.opsli.plugins.excel.annotation.ExcelInfo; /** * 代码模板 Model * -* @author 周鹏程 +* @author Parker * @date 2021-05-27 14:33:49 */ @Data diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/strategy/create/CodeBuilder.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/strategy/create/CodeBuilder.java index d430e2c..794e69b 100644 --- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/strategy/create/CodeBuilder.java +++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/strategy/create/CodeBuilder.java @@ -16,13 +16,11 @@ package org.opsli.plugins.generator.strategy.create; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java index fe6ae5b..8241755 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java @@ -73,6 +73,13 @@ public enum SystemMsg implements BaseMsg { EXCEPTION_USER_HANDLE_SUPER_ADMIN(20313,"不可操作超管账号"), EXCEPTION_USER_SWITCH_TENANT_NOT_HAS_ADMIN(20314,"此租户不存在管理员,不能切换"), EXCEPTION_USER_SWITCH_NOT_ALLOWED(20315,"不允许切换租户"), + EXCEPTION_RESET_PASSWORD(20316,"重制密码失败"), + EXCEPTION_CHANGE_STATUS(20316,"变更用户状态失败"), + EXCEPTION_USER_EMAIL_EQ(20317,"新旧邮箱不可一致"), + EXCEPTION_USER_MOBILE_EQ(20318,"新旧手机不可一致"), + EXCEPTION_USER_MOBILE_UNIQUE(20319,"该手机号已被使用,请先解除原账号手机"), + EXCEPTION_USER_EMAIL_UNIQUE(20320,"该邮箱已被使用,请先解除原账号邮箱"), + /** * 租户 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 5839a52..8890b00 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 @@ -23,45 +23,34 @@ import cn.hutool.core.lang.Snowflake; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.ReflectUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.area.SysAreaRestApi; import org.opsli.api.wrapper.system.area.SysAreaModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.constants.MyBatisConstants; -import org.opsli.common.constants.TreeConstants; import org.opsli.common.utils.FieldUtil; import org.opsli.core.base.controller.BaseRestController; -import org.opsli.core.base.entity.HasChildren; -import org.opsli.core.persistence.querybuilder.QueryBuilder; -import org.opsli.core.persistence.querybuilder.WebQueryBuilder; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.utils.TreeBuildUtil; import org.opsli.modulars.system.area.entity.SysArea; import org.opsli.modulars.system.area.service.ISysAreaService; import org.springframework.core.io.ClassPathResource; -import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.security.access.prepost.PreAuthorize; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.InputStream; -import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; -import java.util.Set; /** * 地域表 Controller @@ -81,24 +70,24 @@ public class SysAreaRestController extends BaseRestController get(SysAreaModel model) { + public ResultWrapper get(SysAreaModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** * 获得组织树树 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得菜单树", notes = "获得菜单树") - @RequiresPermissions("system_area_select") + @PreAuthorize("hasAuthority('system_area_select')") @Override - public ResultVo findTree(String parentId) { + public ResultWrapper findTree(String parentId) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); @@ -121,7 +110,7 @@ public class SysAreaRestController extends BaseRestController IService.hasChildren(parentIds)); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } /** @@ -130,12 +119,12 @@ public class SysAreaRestController extends BaseRestController findTreeAll(Integer deep) { + public ResultWrapper findTreeAll(Integer deep) { List dataList = IService.findList(new QueryWrapper<>()); @@ -156,125 +145,87 @@ public class SysAreaRestController extends BaseRestController IService.hasChildren(parentIds)); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } /** * 地域 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增地域数据", notes = "新增地域数据") - @RequiresPermissions("system_area_insert") - @EnableLog + @PreAuthorize("hasAuthority('system_area_insert')") + @OperateLogger(description = "新增地域数据", + module = ModuleEnum.MODULE_AREA, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(SysAreaModel model) { + public ResultWrapper insert(SysAreaModel model) { // 演示模式 不允许操作 super.demoError(); // 调用新增方法 IService.insert(model); - return ResultVo.success("新增地域成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增地域成功"); } /** * 地域 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改地域数据", notes = "修改地域数据") - @RequiresPermissions("system_area_update") - @EnableLog + @PreAuthorize("hasAuthority('system_area_update')") + @OperateLogger(description = "修改地域数据", + module = ModuleEnum.MODULE_AREA, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(SysAreaModel model) { + public ResultWrapper update(SysAreaModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改地域成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改地域成功"); } /** * 地域 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除地域数据", notes = "删除地域数据") - @RequiresPermissions("system_area_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_area_delete')") + @OperateLogger(description = "删除地域数据", + module = ModuleEnum.MODULE_AREA, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 演示模式 不允许操作 super.demoError(); IService.delete(id); - return ResultVo.success("删除地域成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除地域成功"); } /** * 地域 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除地域数据", notes = "批量删除地域数据") - @RequiresPermissions("system_area_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_area_delete')") + @OperateLogger(description = "批量删除地域数据", + module = ModuleEnum.MODULE_AREA, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 演示模式 不允许操作 super.demoError(); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除地域成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除地域成功"); } - /** - * 地域 Excel 导出 - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_area_export") - @EnableLog - @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(SysAreaRestApi.SUB_TITLE, queryBuilder.build(), response, method); - } - - /** - * 地域 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_area_import") - @EnableLog - @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); - } - - /** - * 地域 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_area_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(SysAreaRestApi.SUB_TITLE, response, method); - } - // ============================== /** 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 f533c97..9bbd6ef 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 @@ -16,23 +16,22 @@ package org.opsli.modulars.system.dict.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.dict.DictDetailApi; import org.opsli.api.wrapper.system.dict.DictDetailModel; import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.exception.ServiceException; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder; @@ -41,11 +40,9 @@ import org.opsli.core.utils.UserUtil; import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.dict.entity.SysDictDetail; import org.opsli.modulars.system.dict.service.IDictDetailService; -import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.security.access.prepost.PreAuthorize; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; import java.util.List; /** @@ -67,13 +64,13 @@ public class DictDetailRestController extends BaseRestController get(DictDetailModel model) { + public ResultWrapper get(DictDetailModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -81,45 +78,47 @@ public class DictDetailRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 数据字典 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增字典明细数据", notes = "新增字典明细数据") - @RequiresPermissions("system_dict_insert") - @EnableLog + @PreAuthorize("hasAuthority('system_dict_insert')") + @OperateLogger(description = "新增字典明细数据", + module = ModuleEnum.MODULE_DICT, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(DictDetailModel model) { + public ResultWrapper insert(DictDetailModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增字典明细数据成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增字典明细数据成功"); } /** * 数据字典 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改字典明细数据", notes = "修改字典明细数据") - @RequiresPermissions("system_dict_update") - @EnableLog + @PreAuthorize("hasAuthority('system_dict_update')") + @OperateLogger(description = "修改字典明细数据", + module = ModuleEnum.MODULE_DICT, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(DictDetailModel model) { + public ResultWrapper update(DictDetailModel model) { if(model != null){ DictDetailModel dictDetailModel = IService.get(model.getId()); @@ -135,20 +134,21 @@ public class DictDetailRestController extends BaseRestController del(String id){ + public ResultWrapper del(String id){ DictDetailModel dictDetailModel = IService.get(id); // 内置数据 只有超级管理员可以修改 @@ -161,20 +161,21 @@ public class DictDetailRestController extends BaseRestController delAll(String ids){ + public ResultWrapper delAll(String ids){ String[] idArray = Convert.toStrArray(ids); if(ids != null){ QueryBuilder queryBuilder = new GenQueryBuilder<>(); @@ -195,61 +196,20 @@ public class DictDetailRestController extends BaseRestController queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(DictDetailApi.SUB_TITLE, queryBuilder.build(), response, method); - } - - /** - * 数据字典 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_dict_import") - @EnableLog - @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); - } - - /** - * 数据字典 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_dict_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(DictDetailApi.SUB_TITLE, response, method); - } - /** * 根据字典类型编号 查询出所有字典 * * @param typeCode 字典类型编号 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "根据字典类型编号 查询出所有字典", notes = "根据字典类型编号 查询出所有字典") @Override - public ResultVo> findListByTypeCode(String typeCode) { - return ResultVo.success(IService.findListByTypeCode(typeCode)); + public ResultWrapper> findListByTypeCode(String typeCode) { + return ResultWrapper.getSuccessResultWrapper( + IService.findListByTypeCode(typeCode)); } } 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 7c6af6e..dd03d47 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 @@ -16,24 +16,23 @@ package org.opsli.modulars.system.dict.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.dict.DictApi; import org.opsli.api.wrapper.system.dict.DictModel; import org.opsli.api.wrapper.system.dict.DictWrapper; import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.exception.ServiceException; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder; @@ -43,11 +42,9 @@ import org.opsli.core.utils.UserUtil; import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.dict.entity.SysDict; import org.opsli.modulars.system.dict.service.IDictService; -import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.security.access.prepost.PreAuthorize; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; import java.util.List; @@ -69,13 +66,13 @@ public class DictRestController extends BaseRestController get(DictModel model) { + public ResultWrapper get(DictModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -83,45 +80,47 @@ public class DictRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 数据字典 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增字典数据", notes = "新增字典数据") - @RequiresPermissions("system_dict_insert") - @EnableLog + @PreAuthorize("hasAuthority('system_dict_insert')") + @OperateLogger(description = "新增字典数据", + module = ModuleEnum.MODULE_DICT, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(DictModel model) { + public ResultWrapper insert(DictModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增字典数据成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增字典数据成功"); } /** * 数据字典 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改字典数据", notes = "修改字典数据") - @RequiresPermissions("system_dict_update") - @EnableLog + @PreAuthorize("hasAuthority('system_dict_update')") + @OperateLogger(description = "修改字典数据", + module = ModuleEnum.MODULE_DICT, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(DictModel model) { + public ResultWrapper update(DictModel model) { if(model != null){ DictModel dictModel = IService.get(model.getId()); @@ -137,20 +136,21 @@ public class DictRestController extends BaseRestController del(String id){ + public ResultWrapper del(String id){ DictModel dictModel = IService.get(id); // 内置数据 只有超级管理员可以修改 @@ -163,20 +163,21 @@ public class DictRestController extends BaseRestController delAll(String ids){ + public ResultWrapper delAll(String ids){ String[] idArray = Convert.toStrArray(ids); if(ids != null){ QueryBuilder queryBuilder = new GenQueryBuilder<>(); @@ -197,65 +198,22 @@ public class DictRestController extends BaseRestController queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(DictApi.SUB_TITLE, queryBuilder.build(), response, method); - } - - /** - * 数据字典 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_dict_import") - @EnableLog - @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); - } - - /** - * 数据字典 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_dict_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(DictApi.SUB_TITLE, response, method); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除字典数据成功"); } /** * 根据字典类型编号 查询出所有字典 * * @param typeCode 字典类型编号 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "根据字典类型编号 查询出所有字典", notes = "根据字典类型编号 查询出所有字典") @Override - public ResultVo getDictListByCode(String typeCode) { + public ResultWrapper getDictListByCode(String typeCode) { List dictList = DictUtil.getDictList(typeCode); if(dictList == null){ - return ResultVo.error("暂无该字典"); + return ResultWrapper.getErrorResultWrapper().setMsg("暂无该字典"); } - return ResultVo.success(dictList); + return ResultWrapper.getSuccessResultWrapper(dictList); } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/EmailCodeModel.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/EmailCodeModel.java new file mode 100644 index 0000000..1ebb952 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/EmailCodeModel.java @@ -0,0 +1,42 @@ +/** + * 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.modulars.system.login.dto; + +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +/** + * 邮箱 + * + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Data +public class EmailCodeModel { + + /** 邮箱 */ + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_EMAIL}) + @ValidatorLenMax(50) + private String email; + + /** 类型 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(50) + private String type; + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/LoginCodeModel.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/LoginCodeModel.java new file mode 100644 index 0000000..364e053 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/LoginCodeModel.java @@ -0,0 +1,44 @@ +/** + * 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.modulars.system.login.dto; + +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +/** + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Data +public class LoginCodeModel { + + /** 主键 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(50) + private String principal; + + /** 验证码 */ + @ValidatorLenMax(20) + private String verificationCode; + + /** 登录来源: 0:PC端;1:APP-安卓 2:APP-IOS 3:小程序 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(5) + private String loginFrom; + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/entity/LoginForm.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/LoginModel.java similarity index 68% rename from opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/entity/LoginForm.java rename to opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/LoginModel.java index 254cd38..41b8919 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/entity/LoginForm.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/LoginModel.java @@ -13,46 +13,43 @@ * License for the specific language governing permissions and limitations under * the License. */ -package org.opsli.modulars.system.login.entity; +package org.opsli.modulars.system.login.dto; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import lombok.EqualsAndHashCode; -import org.opsli.api.base.encrypt.BaseEncrypt; import org.opsli.common.annotation.validator.Validator; import org.opsli.common.annotation.validator.ValidatorLenMax; import org.opsli.common.annotation.validator.ValidatorLenMin; import org.opsli.common.enums.ValidatorType; /** - * 登录表单 - * * @author Parker - * @date 2020-11-28 18:59:59 - */ + * @date 2022-07-16 8:14 PM + **/ @Data -@EqualsAndHashCode(callSuper = false) -public class LoginForm extends BaseEncrypt { +public class LoginModel { - /** 用户名 */ - @ApiModelProperty(value = "用户名") - @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL}) + /** 主键 */ + @Validator({ValidatorType.IS_NOT_NULL}) @ValidatorLenMax(50) - private String username; + private String principal; /** 密码 */ - @ApiModelProperty(value = "密码") @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_SECURITY_PASSWORD}) @ValidatorLenMin(6) private String password; /** 验证码 */ - @ApiModelProperty(value = "验证码") - @ValidatorLenMax(30) - private String captcha; + @ValidatorLenMax(20) + private String verificationCode; /** UUID */ @ApiModelProperty(value = "UUID") private String uuid; + /** 登录来源: 0:PC端;1:APP-安卓 2:APP-IOS 3:小程序 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(5) + private String loginFrom; + } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/MobileCodeModel.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/MobileCodeModel.java new file mode 100644 index 0000000..056b140 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/dto/MobileCodeModel.java @@ -0,0 +1,42 @@ +/** + * 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.modulars.system.login.dto; + +import lombok.Data; +import org.opsli.common.annotation.validator.Validator; +import org.opsli.common.annotation.validator.ValidatorLenMax; +import org.opsli.common.enums.ValidatorType; + +/** + * 手机号 + * + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Data +public class MobileCodeModel { + + /** 手机号 */ + @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_MOBILE}) + @ValidatorLenMax(50) + private String mobile; + + + /** 类型 */ + @Validator({ValidatorType.IS_NOT_NULL}) + @ValidatorLenMax(50) + private String type; +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/event/BadCredentialsEvent.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/event/BadCredentialsEvent.java new file mode 100644 index 0000000..a57e400 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/event/BadCredentialsEvent.java @@ -0,0 +1,81 @@ +/** + * 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.modulars.system.login.event; + +import com.google.common.eventbus.Subscribe; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.common.constants.RedisConstants; +import org.opsli.common.enums.LoginModelType; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.plugins.redis.RedisPlugin; +import org.opsli.plugins.security.eventbus.ISecurityEventConsumer; +import org.opsli.plugins.security.eventdto.BadCredentials; +import org.springframework.stereotype.Component; + +/** + * 登陆凭证错误事件 + * + * @author Parker + * @date 2022-07-20 10:37:58 + */ +@Slf4j +@AllArgsConstructor +@Component +public class BadCredentialsEvent implements ISecurityEventConsumer { + + private final RedisPlugin redisPlugin; + + /** + * 如果 选择凭证模式登陆 且失败的情况下 超过一定次数 冻结一段时间账号 + * @param badCredentials 事件 + */ + @Override + @Subscribe + public void consumer(BadCredentials badCredentials) { + // 失败锁定时间 + Integer slipLockSpeed = UserTokenUtil.LOGIN_PROPERTIES.getSlipLockSpeed(); + // 失败次数 + Integer slipCount = UserTokenUtil.LOGIN_PROPERTIES.getSlipCount(); + + // 登陆类型 + LoginModelType loginModelType = + LoginModelType.getTypeByStr(badCredentials.getPrincipal()); + + // 锁定数量 缓存Key + String countKey = CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + + loginModelType.name().toLowerCase() + ":" + badCredentials.getPrincipal()); + // 锁定 缓存Key + String localKey = CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + + loginModelType.name().toLowerCase() + ":" + badCredentials.getPrincipal()); + + // 如果失败次数 超过阈值 则锁定账号 + Long slipNum = redisPlugin.increment(countKey); + if (slipNum != null){ + // 设置失效时间为 5分钟 + redisPlugin.expire(countKey, slipLockSpeed); + + // 如果确认 都失败 则存入临时缓存 + if(slipNum >= slipCount){ + long currentTimeMillis = System.currentTimeMillis(); + // 存入Redis + redisPlugin.put(localKey, currentTimeMillis, slipLockSpeed); + } + } + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginCodeModelVerifyCodeBeforeHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginCodeModelVerifyCodeBeforeHandler.java new file mode 100644 index 0000000..342e670 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginCodeModelVerifyCodeBeforeHandler.java @@ -0,0 +1,59 @@ +/** + * 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.modulars.system.login.handler.before; + +import lombok.AllArgsConstructor; +import org.opsli.common.enums.LoginModelType; +import org.opsli.common.enums.VerificationTypeEnum; +import org.opsli.core.utils.VerificationCodeUtil; +import org.opsli.modulars.system.login.dto.LoginCodeModel; +import org.opsli.plugins.security.handler.LoginBeforeListener; +import org.springframework.stereotype.Component; + +/** + * 验证账号与验证码 (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginCodeModelVerifyCodeBeforeHandler implements LoginBeforeListener { + + @Override + public Class getModelType() { + return LoginCodeModel.class; + } + + @Override + public void handle(Object model) { + LoginCodeModel loginCodeModel = (LoginCodeModel) model; + + String principal = loginCodeModel.getPrincipal(); + + // 校验验证码 + LoginModelType loginModelType = LoginModelType.getTypeByStr(loginCodeModel.getPrincipal()); + if(LoginModelType.EMAIL == loginModelType){ + VerificationCodeUtil + .checkEmailCode( + principal, loginCodeModel.getVerificationCode(), VerificationTypeEnum.LOGIN.getType()); + }else if(LoginModelType.MOBILE == loginModelType){ + VerificationCodeUtil + .checkMobileCode( + principal, loginCodeModel.getVerificationCode(), VerificationTypeEnum.LOGIN.getType()); + } + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginModelVerifyCaptchaBeforeHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginModelVerifyCaptchaBeforeHandler.java new file mode 100644 index 0000000..badab99 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginModelVerifyCaptchaBeforeHandler.java @@ -0,0 +1,52 @@ +/** + * 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.modulars.system.login.handler.before; + +import lombok.AllArgsConstructor; +import org.opsli.core.utils.CaptchaUtil; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.modulars.system.login.dto.LoginModel; +import org.opsli.plugins.security.handler.LoginBeforeListener; +import org.springframework.stereotype.Component; + +/** + * 验证账号与验证码 (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginModelVerifyCaptchaBeforeHandler implements LoginBeforeListener { + + @Override + public Class getModelType() { + return LoginModel.class; + } + + @Override + public void handle(Object model) { + LoginModel loginModel = (LoginModel) model; + + // 获得失败次数 + long slipCount = UserTokenUtil.getSlipCount(loginModel.getPrincipal()); + + // 失败次数超过 验证次数阈值 开启验证码验证 + if(slipCount >= UserTokenUtil.LOGIN_PROPERTIES.getSlipVerifyCount()){ + CaptchaUtil.validate(loginModel.getUuid(), loginModel.getVerificationCode()); + } + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginModelVerifyTempLockedBeforeHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginModelVerifyTempLockedBeforeHandler.java new file mode 100644 index 0000000..c74ee0b --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/before/LoginModelVerifyTempLockedBeforeHandler.java @@ -0,0 +1,93 @@ +/** + * 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.modulars.system.login.handler.before; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import org.opsli.common.constants.RedisConstants; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.msg.TokenMsg; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.modulars.system.login.dto.LoginModel; +import org.opsli.common.enums.LoginModelType; +import org.opsli.plugins.redis.RedisPlugin; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.handler.LoginBeforeListener; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * 验证账号临时锁定 (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginModelVerifyTempLockedBeforeHandler implements LoginBeforeListener { + + private final RedisPlugin redisPlugin; + + @Override + public Class getModelType() { + return LoginModel.class; + } + + @Override + public void handle(Object model) { + + // 失败锁定时间 + Integer slipLockSpeed = UserTokenUtil.LOGIN_PROPERTIES.getSlipLockSpeed(); + + LoginModel loginModel = (LoginModel) model; + + String principal = loginModel.getPrincipal(); + + // 登陆类型 + LoginModelType loginModelType = LoginModelType.getTypeByStr(loginModel.getPrincipal()); + + String key = CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + + loginModelType.name().toLowerCase() + ":" + principal); + + // 判断账号是否临时锁定 + Long loseTimeMillis = Convert.toLong(redisPlugin.get(key)); + if(loseTimeMillis != null){ + Date currDate = DateUtil.date(); + DateTime loseDate = DateUtil.date(loseTimeMillis); + // 偏移5分钟 + DateTime currLoseDate = DateUtil.offsetSecond(loseDate, slipLockSpeed); + + // 计算失效剩余时间( 分 ) + long betweenM = DateUtil.between(currLoseDate, currDate, DateUnit.MINUTE); + if(betweenM > 0){ + String msg = StrUtil.format(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getMessage() + ,betweenM + "分钟"); + throw new AuthException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getCode(), msg); + }else{ + // 计算失效剩余时间( 秒 ) + long betweenS = DateUtil.between(currLoseDate, currDate, DateUnit.SECOND); + String msg = StrUtil.format(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getMessage() + ,betweenS + "秒"); + throw new AuthException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCK.getCode(), msg); + } + } + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/error/BizServiceErrorHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/error/BizServiceErrorHandler.java new file mode 100644 index 0000000..78f6223 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/error/BizServiceErrorHandler.java @@ -0,0 +1,65 @@ +/** + * 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.modulars.system.login.handler.error; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.common.exception.ServiceException; +import org.opsli.plugins.security.handler.LoginAccessDeniedListener; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 业务异常 处理器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@Slf4j +@AllArgsConstructor +@Component +public class BizServiceErrorHandler implements LoginAccessDeniedListener { + + @Override + public boolean handle(Object loginModel, HttpServletRequest request, HttpServletResponse response, Exception e) { + if(!(e instanceof ServiceException)){ + return true; + } + + ServiceException se = (ServiceException) e; + + Integer code = se.getCode(); + String errorMessage = se.getErrorMessage(); + + // 记录告警日志 + log.warn("认证服务异常(ServiceException) => 认证信息:{} 异常编码:{} 异常:{}", + JSONUtil.toJsonStr(loginModel), + code, + errorMessage); + + AuthResultWrapper resultVo = + AuthResultWrapper.getCustomResultWrapper(code, errorMessage); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(resultVo)); + + return false; + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginClearErrorSuccessHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginClearErrorSuccessHandler.java new file mode 100644 index 0000000..37a81bb --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginClearErrorSuccessHandler.java @@ -0,0 +1,106 @@ +/** + * 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.modulars.system.login.handler.success; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.constants.RedisConstants; +import org.opsli.common.enums.LoginModelType; +import org.opsli.core.cache.CacheUtil; +import org.opsli.core.utils.UserUtil; +import org.opsli.plugins.redis.RedisPlugin; +import org.opsli.plugins.security.handler.LoginAccessSuccessListener; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 登陆成功后 清除错误记录 (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginClearErrorSuccessHandler implements LoginAccessSuccessListener { + + private final RedisPlugin redisPlugin; + + @Override + public void handle( + Object model, Authentication authenticate, + HttpServletRequest request, HttpServletResponse response) { + // 1. 获取认证用户 + UserDetails userDetails = (UserDetails) authenticate.getPrincipal(); + + // 2. 获取认证用户其他信息 + UserModel userModel = UserUtil.getUserByUserName(userDetails.getUsername()); + + // 3. 清除错误记录 + List delKeyList = Lists.newArrayListWithCapacity(6); + + // 账号 + if(StrUtil.isNotEmpty(userModel.getUsername())){ + // 获得当前失败次数 + String countKey = CacheUtil.formatKey( + RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + LoginModelType.ACCOUNT.name().toLowerCase() + + ":" + userModel.getUsername()); + // 获得当前失败锁定状态 + String lockKey = CacheUtil.formatKey( + RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + LoginModelType.ACCOUNT.name().toLowerCase() + + ":" + userModel.getUsername()); + delKeyList.add(countKey); + delKeyList.add(lockKey); + } + + // 手机 + if(StrUtil.isNotEmpty(userModel.getMobile())){ + // 手机 - 获得当前失败次数 + String countKey = CacheUtil.formatKey( + RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + LoginModelType.MOBILE.name().toLowerCase() + + ":" + userModel.getMobile()); + // 手机 - 获得当前失败锁定状态 + String lockKey = CacheUtil.formatKey( + RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + LoginModelType.MOBILE.name().toLowerCase() + + ":" + userModel.getMobile()); + delKeyList.add(countKey); + delKeyList.add(lockKey); + } + + // 邮箱 + if(StrUtil.isNotEmpty(userModel.getEmail())){ + // 获得当前失败次数 + String countKey = CacheUtil.formatKey( + RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + LoginModelType.EMAIL.name().toLowerCase() + + ":" + userModel.getEmail()); + // 获得当前失败锁定状态 + String lockKey = CacheUtil.formatKey( + RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + LoginModelType.EMAIL.name().toLowerCase() + + ":" + userModel.getEmail()); + delKeyList.add(countKey); + delKeyList.add(lockKey); + } + + // 批量删除 + redisPlugin.del(delKeyList); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginCodeModelCreateAccessTokenHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginCodeModelCreateAccessTokenHandler.java new file mode 100644 index 0000000..5cf2a6b --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginCodeModelCreateAccessTokenHandler.java @@ -0,0 +1,99 @@ +/** + * 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.modulars.system.login.handler.success; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.core.base.dto.LoginUserDto; +import org.opsli.core.utils.JWTBizUtil; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.core.utils.UserUtil; +import org.opsli.modulars.system.login.dto.LoginCodeModel; +import org.opsli.core.utils.CryptoUtil; +import org.opsli.modulars.system.login.vo.AuthAccessTokenDto; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.handler.LoginAccessSuccessListener; +import org.opsli.plugins.security.utils.IpaddrUtil; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * 生成认证 Token (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginCodeModelCreateAccessTokenHandler implements LoginAccessSuccessListener { + + @Override + public Class getModelType() { + return LoginCodeModel.class; + } + + @Override + public void handle( + Object model, Authentication authenticate, + HttpServletRequest request, HttpServletResponse response) { + LoginCodeModel loginModel = (LoginCodeModel) model; + + // 1. 获取认证用户 + UserDetails userDetails = (UserDetails) authenticate.getPrincipal(); + + // 2. 获取认证用户其他信息 + UserModel userModel = UserUtil.getUserByUserName(userDetails.getUsername()); + if(null == userModel){ + throw new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID); + } + + LoginUserDto loginUser = LoginUserDto.builder() + .uid(userModel.getId()) + .tenantId(userModel.getTenantId()) + .username(userDetails.getUsername()) + .nickname(userModel.getRealName()) + .loginIp(IpaddrUtil.getClientIdBySingle(request)) + .loginFrom(loginModel.getLoginFrom()) + .mobile(userModel.getMobile()) + .email(userModel.getUsername()) + .build(); + + String accessToken = UserTokenUtil.createAccessToken(loginUser); + + // 数据传输DTO + AuthAccessTokenDto accessTokenDto = AuthAccessTokenDto.builder() + .accessToken(accessToken) + .expiresAtTs(JWTBizUtil.getExpiredDateFromToken(accessToken).getTime()) + .build(); + + // 对称加密数据 + String symmetricEncryptToStr = CryptoUtil.symmetricEncryptToStr(accessTokenDto); + + AuthResultWrapper successResultWrapper = + AuthResultWrapper.getSuccessResultWrapper(symmetricEncryptToStr); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(successResultWrapper)); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginModelClearCaptchaSuccessHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginModelClearCaptchaSuccessHandler.java new file mode 100644 index 0000000..1630988 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginModelClearCaptchaSuccessHandler.java @@ -0,0 +1,59 @@ +/** + * 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.modulars.system.login.handler.success; + +import lombok.AllArgsConstructor; +import org.opsli.core.utils.CaptchaUtil; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.modulars.system.login.dto.LoginModel; +import org.opsli.plugins.security.handler.LoginAccessSuccessListener; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 登陆成功后 清除验证码信息 (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginModelClearCaptchaSuccessHandler implements LoginAccessSuccessListener { + + @Override + public Class getModelType() { + return LoginModel.class; + } + + @Override + public void handle( + Object model, Authentication authenticate, + HttpServletRequest request, HttpServletResponse response) { + + LoginModel loginModel = (LoginModel) model; + + // 获得失败次数 + long slipCount = UserTokenUtil.getSlipCount(loginModel.getPrincipal()); + + if(slipCount >= UserTokenUtil.LOGIN_PROPERTIES.getSlipVerifyCount()){ + // 删除验证过后验证码 + CaptchaUtil.delCaptcha(loginModel.getUuid()); + } + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginModelCreateAccessTokenHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginModelCreateAccessTokenHandler.java new file mode 100644 index 0000000..156d96f --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginModelCreateAccessTokenHandler.java @@ -0,0 +1,99 @@ +/** + * 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.modulars.system.login.handler.success; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.core.base.dto.LoginUserDto; +import org.opsli.core.utils.JWTBizUtil; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.core.utils.UserUtil; +import org.opsli.modulars.system.login.dto.LoginModel; +import org.opsli.core.utils.CryptoUtil; +import org.opsli.modulars.system.login.vo.AuthAccessTokenDto; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.handler.LoginAccessSuccessListener; +import org.opsli.plugins.security.utils.IpaddrUtil; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * 生成认证 Token (LoginModel) + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginModelCreateAccessTokenHandler implements LoginAccessSuccessListener { + + @Override + public Class getModelType() { + return LoginModel.class; + } + + @Override + public void handle( + Object model, Authentication authenticate, + HttpServletRequest request, HttpServletResponse response) { + LoginModel loginModel = (LoginModel) model; + + // 1. 获取认证用户 + UserDetails userDetails = (UserDetails) authenticate.getPrincipal(); + + // 2. 获取认证用户其他信息 + UserModel userModel = UserUtil.getUserByUserName(userDetails.getUsername()); + if(null == userModel){ + throw new AuthException(AuthErrorCodeEnum.AUTH_AUTH_INVALID); + } + + LoginUserDto loginUser = LoginUserDto.builder() + .uid(userModel.getId()) + .tenantId(userModel.getTenantId()) + .username(userDetails.getUsername()) + .nickname(userModel.getRealName()) + .loginIp(IpaddrUtil.getClientIdBySingle(request)) + .loginFrom(loginModel.getLoginFrom()) + .mobile(userModel.getMobile()) + .email(userModel.getUsername()) + .build(); + + String accessToken = UserTokenUtil.createAccessToken(loginUser); + + // 数据传输DTO + AuthAccessTokenDto accessTokenDto = AuthAccessTokenDto.builder() + .accessToken(accessToken) + .expiresAtTs(JWTBizUtil.getExpiredDateFromToken(accessToken).getTime()) + .build(); + + // 对称加密数据 + String symmetricEncryptToStr = CryptoUtil.symmetricEncryptToStr(accessTokenDto); + + AuthResultWrapper successResultWrapper = + AuthResultWrapper.getSuccessResultWrapper(symmetricEncryptToStr); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(successResultWrapper)); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginSuccessAfterVerifyHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginSuccessAfterVerifyHandler.java new file mode 100644 index 0000000..8d0e596 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginSuccessAfterVerifyHandler.java @@ -0,0 +1,99 @@ +/** + * 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.modulars.system.login.handler.success; + +import cn.hutool.core.collection.CollUtil; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.opsli.api.wrapper.system.menu.MenuModel; +import org.opsli.api.wrapper.system.tenant.TenantModel; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.enums.DictType; +import org.opsli.common.exception.TokenException; +import org.opsli.core.msg.TokenMsg; +import org.opsli.core.utils.TenantUtil; +import org.opsli.core.utils.UserUtil; +import org.opsli.plugins.security.handler.LoginAccessSuccessListener; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 登陆成功后 验证器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginSuccessAfterVerifyHandler implements LoginAccessSuccessListener { + + @Override + public void handle( + Object model, Authentication authenticate, + HttpServletRequest request, HttpServletResponse response) { + // 1. 获取认证用户 + UserDetails userDetails = (UserDetails) authenticate.getPrincipal(); + + // 2. 获取认证用户其他信息 + UserModel user = UserUtil.getUserByUserName(userDetails.getUsername()); + + // 如果不是超级管理员 则要进行安全验证 + if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){ + + // 如果不是 系统用户, 也就是租户用户 需要验证租户启用情况 + if(!TenantUtil.SUPER_ADMIN_TENANT_ID.equals(user.getTenantId())){ + // 验证租户是否生效 + TenantModel tenant = TenantUtil.getTenant(user.getTenantId()); + if(tenant == null){ + throw new TokenException(TokenMsg.EXCEPTION_LOGIN_TENANT_NOT_USABLE); + } + } + + // 账号锁定验证 + if(StringUtils.isEmpty(user.getEnable()) || + DictType.NO_YES_NO.getValue().equals(user.getEnable())){ + // 账号已被锁定,请联系管理员 + throw new TokenException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCKED); + } + + // 检测用户是否有角色 + List roleModelList = UserUtil.getUserRolesByUserId(user.getId()); + if(CollUtil.isEmpty(roleModelList)){ + // 用户暂无角色,请设置后登录 + throw new TokenException(TokenMsg.EXCEPTION_USER_ROLE_NOT_NULL); + } + + // 检测用户是否有角色菜单 + List menuModelList = UserUtil.getMenuListByUserId(user.getId()); + if(CollUtil.isEmpty(menuModelList)){ + // 用户暂无角色菜单,请设置后登录 + throw new TokenException(TokenMsg.EXCEPTION_USER_MENU_NOT_NULL); + } + + // 检测用户是否有角色权限 + List userAllPermsList = UserUtil.getUserAllPermsByUserId(user.getId()); + if(CollUtil.isEmpty(userAllPermsList)){ + // 用户暂无角色菜单,请设置后登录 + throw new TokenException(TokenMsg.EXCEPTION_USER_PERMS_NOT_NULL); + } + } + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginSuccessLogHandler.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginSuccessLogHandler.java new file mode 100644 index 0000000..4ac8a03 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/handler/success/LoginSuccessLogHandler.java @@ -0,0 +1,68 @@ +/** + * 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.modulars.system.login.handler.success; + +import lombok.AllArgsConstructor; +import org.opsli.api.wrapper.system.logs.LoginLogsModel; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.enums.LoginFromEnum; +import org.opsli.core.utils.UserUtil; +import org.opsli.modulars.system.logs.factory.UserLoginLogFactory; +import org.opsli.plugins.security.eventbus.SpringSecurityEventBus; +import org.opsli.plugins.security.handler.LoginAccessSuccessListener; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 登陆成功日志执行器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@AllArgsConstructor +@Component +public class LoginSuccessLogHandler implements LoginAccessSuccessListener { + + private final SpringSecurityEventBus springSecurityEventBus; + + @Override + public void handle( + Object model, Authentication authenticate, + HttpServletRequest request, HttpServletResponse response) { + // 1. 获取认证用户 + UserDetails userDetails = (UserDetails) authenticate.getPrincipal(); + + // 2. 获取认证用户其他信息 + UserModel userModel = UserUtil.getUserByUserName(userDetails.getUsername()); + if(null == userModel){ + return; + } + + // 3. 生成登陆日志 + LoginLogsModel userLoginModel = + UserLoginLogFactory.getUserLoginModel(request, userModel, true); + + // 设置登陆来源 + LoginFromEnum loginFrom = LoginFromEnum.getByBean(model); + userLoginModel.setLoginFrom(loginFrom.getType()); + + springSecurityEventBus.post(userLoginModel); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/vo/AuthAccessAndRefreshTokenDto.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/vo/AuthAccessAndRefreshTokenDto.java new file mode 100644 index 0000000..a65c7a7 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/vo/AuthAccessAndRefreshTokenDto.java @@ -0,0 +1,46 @@ +/** + * 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.modulars.system.login.vo; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + * 登录 Token 传输实体 + * + * @author Parker + * @since 2021-12-27 + */ +@Getter +@Setter +@Builder +public class AuthAccessAndRefreshTokenDto implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 刷新Token */ + private String refreshToken; + + /** 认证Token */ + private String accessToken; + + /** 失效时间戳 */ + private Long expiresAtTs; + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/vo/AuthAccessTokenDto.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/vo/AuthAccessTokenDto.java new file mode 100644 index 0000000..c0ae3d6 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/vo/AuthAccessTokenDto.java @@ -0,0 +1,43 @@ +/** + * 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.modulars.system.login.vo; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + * 登录 Token 传输实体 + * + * @author Parker + * @since 2021-12-27 + */ +@Getter +@Setter +@Builder +public class AuthAccessTokenDto implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 认证Token */ + private String accessToken; + + /** 失效时间戳 */ + private Long expiresAtTs; + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginByAccountRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginByAccountRestController.java new file mode 100644 index 0000000..e4f7625 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginByAccountRestController.java @@ -0,0 +1,182 @@ +/** + * 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.modulars.system.login.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.opsli.common.annotation.Limiter; +import org.opsli.common.enums.AlertType; +import org.opsli.common.enums.LoginModelType; +import org.opsli.common.utils.WrapperUtil; +import org.opsli.core.utils.CaptchaUtil; +import org.opsli.core.utils.ValidatorUtil; +import org.opsli.api.base.encrypt.EncryptModel; +import org.opsli.modulars.system.login.dto.LoginModel; +import org.opsli.modulars.system.login.handler.before.LoginModelVerifyCaptchaBeforeHandler; +import org.opsli.modulars.system.login.handler.before.LoginModelVerifyTempLockedBeforeHandler; +import org.opsli.modulars.system.login.handler.error.BizServiceErrorHandler; +import org.opsli.modulars.system.login.handler.success.*; +import org.opsli.core.utils.CryptoUtil; +import org.opsli.plugins.security.authentication.EmailPasswordAuthenticationToken; +import org.opsli.plugins.security.authentication.MobilePasswordAuthenticationToken; +import org.opsli.plugins.security.handler.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 账号 + 密码 登录 + * 不需要继承 api 接口 + * + * @author parker + * @date 2020-05-23 13:30 + */ +@Api(tags = "登录相关") +@Slf4j +@RestController +public class LoginByAccountRestController { + + private LoginHandler loginHandler; + + /** + * 验证码 + * + * @param uuid 随机UUID + */ + @Limiter(alertType = AlertType.ALERT) + @ApiOperation(value = "验证码", notes = "验证码") + @GetMapping("captcha") + public void captcha(String uuid, HttpServletResponse response) throws IOException { + ServletOutputStream out = response.getOutputStream(); + if(out != null){ + response.setHeader("Cache-Control", "no-store, no-cache"); + //生成图片验证码 + CaptchaUtil.createCaptcha(uuid, out); + } + } + + @Limiter + @ApiOperation(value = "账号+密码 登录", notes = "账号+密码 登录") + @PostMapping("/system/login") + public void login(@RequestBody EncryptModel encryptModel){ + // 验证加密登录对象 + ValidatorUtil.verify(encryptModel); + + // 解密对象 + Object dataToObj = CryptoUtil + .asymmetricDecryptToObj(encryptModel.getEncryptData()); + + // 转换模型 + LoginModel loginModel = WrapperUtil.transformInstance(dataToObj, LoginModel.class); + + // 验证登录对象 + ValidatorUtil.verify(loginModel); + + loginHandler.login(loginModel, + model -> { + String principal = loginModel.getPrincipal(); + LoginModelType loginModelType = LoginModelType.getTypeByStr(principal); + Authentication authentication = null; + switch (loginModelType) { + case MOBILE: + authentication = + new MobilePasswordAuthenticationToken(principal, model.getPassword()); + break; + case EMAIL: + authentication = + new EmailPasswordAuthenticationToken(principal, model.getPassword()); + break; + case ACCOUNT: + authentication = + new UsernamePasswordAuthenticationToken(principal, model.getPassword()); + default: + break; + } + return authentication; + } + ); + } + + /** + * 初始化 + */ + @Autowired + public void init( + AuthenticationManager authenticationManager, + LoginModelVerifyTempLockedBeforeHandler loginModelVerifyTempLockedBeforeHandler, + LoginModelVerifyCaptchaBeforeHandler loginModelVerifyCaptchaBeforeHandler, + LoginModelCreateAccessTokenHandler loginModelCreateAccessTokenHandler, + LoginSuccessAfterVerifyHandler loginSuccessAfterVerifyHandler, + LoginClearErrorSuccessHandler loginClearErrorSuccessHandler, + LoginModelClearCaptchaSuccessHandler loginModelClearCaptchaSuccessHandler, + LoginSuccessLogHandler loginSuccessLogHandler, + AuthServiceErrorHandler authServiceErrorHandler, + BizServiceErrorHandler bizServiceErrorHandler, + OtherErrorHandler otherErrorHandler, + AuthErrorHandler authErrorHandler, + SecurityErrorHandler securityErrorHandler ){ + + loginHandler = new LoginHandler.Builder() + .initAuthenticationManager(authenticationManager) + .initLoginModelClass(LoginModel.class) + // 前置处理器 + .before() + // 验证账号是否临时冻结 + .addListener(loginModelVerifyTempLockedBeforeHandler) + // 超过登陆失败次数 需要校验验证码 + .addListener(loginModelVerifyCaptchaBeforeHandler) + .and() + // 成功处理 + .accessSuccess() + // 返回 记录登录日志信息 + .addListener(loginSuccessLogHandler) + // 清除错误日志 + .addListener(loginClearErrorSuccessHandler) + // 清除对应验证码信息 + .addListener(loginModelClearCaptchaSuccessHandler) + // 登陆成功后 验证用户其他相关信息 + .addListener(loginSuccessAfterVerifyHandler) + // 返回 accessToken + .addListener(loginModelCreateAccessTokenHandler) + .and() + // 异常处理 + .accessDenied() + // 增加认证服务异常处理器 + .addListener(authServiceErrorHandler) + // 增加认证异常处理器 + .addListener(authErrorHandler) + // 增加账户认证异常处理器 + .addListener(securityErrorHandler) + // 增加内部业务异常处理器 + .addListener(bizServiceErrorHandler) + // 增加其他未捕获异常处理器 + .addListener(otherErrorHandler) + .and() + .build(); + } + + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginByCodeRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginByCodeRestController.java new file mode 100644 index 0000000..62bc50d --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginByCodeRestController.java @@ -0,0 +1,150 @@ +/** + * 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.modulars.system.login.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.base.encrypt.EncryptModel; +import org.opsli.common.annotation.Limiter; +import org.opsli.common.enums.LoginModelType; +import org.opsli.common.utils.WrapperUtil; +import org.opsli.core.utils.ValidatorUtil; +import org.opsli.modulars.system.login.dto.LoginCodeModel; +import org.opsli.modulars.system.login.handler.before.LoginCodeModelVerifyCodeBeforeHandler; +import org.opsli.modulars.system.login.handler.error.BizServiceErrorHandler; +import org.opsli.modulars.system.login.handler.success.LoginClearErrorSuccessHandler; +import org.opsli.modulars.system.login.handler.success.LoginCodeModelCreateAccessTokenHandler; +import org.opsli.modulars.system.login.handler.success.LoginSuccessAfterVerifyHandler; +import org.opsli.modulars.system.login.handler.success.LoginSuccessLogHandler; +import org.opsli.core.utils.CryptoUtil; +import org.opsli.plugins.security.authentication.EmailCodeAuthenticationToken; +import org.opsli.plugins.security.authentication.MobileCodeAuthenticationToken; +import org.opsli.plugins.security.handler.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 手机号/邮箱+验证码 登录 + * 不需要继承 api 接口 + * + * @author parker + * @date 2020-05-23 13:30 + */ +@Api(tags = "登录相关") +@Slf4j +@RestController +public class LoginByCodeRestController { + + private LoginHandler loginHandler; + + + @Limiter + @ApiOperation(value = "手机号/邮箱+验证码 登录", notes = "手机号/邮箱+验证码 登录") + @PostMapping("/system/login-by-code") + public void login(@RequestBody EncryptModel encryptModel){ + // 验证加密登录对象 + ValidatorUtil.verify(encryptModel); + + // 解密对象 + Object dataToObj = CryptoUtil + .asymmetricDecryptToObj(encryptModel.getEncryptData()); + + // 转换模型 + LoginCodeModel loginCodeModel = WrapperUtil.transformInstance(dataToObj, LoginCodeModel.class); + + // 验证登录对象 + ValidatorUtil.verify(loginCodeModel); + + loginHandler.login(loginCodeModel, + model -> { + String principal = loginCodeModel.getPrincipal(); + LoginModelType loginModelType = LoginModelType.getTypeByStr(principal); + Authentication authentication = null; + switch (loginModelType) { + case MOBILE: + authentication = + new MobileCodeAuthenticationToken(principal, model.getVerificationCode()); + break; + case EMAIL: + authentication = + new EmailCodeAuthenticationToken(principal, model.getVerificationCode()); + break; + default: + break; + } + return authentication; + } + ); + } + + /** + * 初始化 + */ + @Autowired + public void init( + AuthenticationManager authenticationManager, + LoginCodeModelVerifyCodeBeforeHandler loginCodeModelVerifyCodeBeforeHandler, + LoginCodeModelCreateAccessTokenHandler loginCodeModelCreateAccessTokenHandler, + LoginSuccessAfterVerifyHandler loginSuccessAfterVerifyHandler, + LoginClearErrorSuccessHandler loginClearErrorSuccessHandler, + LoginSuccessLogHandler loginSuccessLogHandler, + AuthServiceErrorHandler authServiceErrorHandler, + BizServiceErrorHandler bizServiceErrorHandler, + OtherErrorHandler otherErrorHandler, + AuthErrorHandler authErrorHandler, + SecurityErrorHandler securityErrorHandler ){ + + loginHandler = new LoginHandler.Builder() + .initAuthenticationManager(authenticationManager) + .initLoginModelClass(LoginCodeModel.class) + // 前置处理器 + .before() + // 校验验证码 + .addListener(loginCodeModelVerifyCodeBeforeHandler) + .and() + // 成功处理 + .accessSuccess() + // 返回 记录登录日志信息 + .addListener(loginSuccessLogHandler) + // 清除错误日志 + .addListener(loginClearErrorSuccessHandler) + // 登陆成功后 验证用户其他相关信息 + .addListener(loginSuccessAfterVerifyHandler) + // 返回 accessToken + .addListener(loginCodeModelCreateAccessTokenHandler) + .and() + // 异常处理 + .accessDenied() + // 增加认证服务异常处理器 + .addListener(authServiceErrorHandler) + // 增加认证异常处理器 + .addListener(authErrorHandler) + // 增加账户认证异常处理器 + .addListener(securityErrorHandler) + // 增加内部业务异常处理器 + .addListener(bizServiceErrorHandler) + // 增加其他未捕获异常处理器 + .addListener(otherErrorHandler) + .and() + .build(); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginCommonRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginCommonRestController.java new file mode 100644 index 0000000..53579b6 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginCommonRestController.java @@ -0,0 +1,105 @@ +/** + * 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.modulars.system.login.web; + +import com.google.common.collect.Maps; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.wrapper.system.logs.LoginLogsModel; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.annotation.Limiter; +import org.opsli.common.exception.TokenException; +import org.opsli.core.base.dto.LoginUserDto; +import org.opsli.core.holder.UserContextHolder; +import org.opsli.core.msg.TokenMsg; +import org.opsli.core.utils.UserTokenUtil; +import org.opsli.core.utils.UserUtil; +import org.opsli.modulars.system.logs.factory.UserLoginLogFactory; +import org.opsli.plugins.security.eventbus.SpringSecurityEventBus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * 登陆 公共服务 + * 不需要继承 api 接口 + * + * @author parker + * @date 2020-05-23 13:30 + */ +@Api(tags = "登录相关") +@Slf4j +@AllArgsConstructor +@RestController +public class LoginCommonRestController { + + private final SpringSecurityEventBus springSecurityEventBus; + + /** + * 获得当前登录失败次数 + */ + @Limiter + @ApiOperation(value = "获得当前登录失败次数", notes = "获得当前登录失败次数") + @GetMapping("/system/slipCount") + public ResultWrapper slipCount(String username){ + // 获得当前失败次数 + long slipCount = UserTokenUtil.getSlipCount(username); + Map ret = Maps.newHashMap(); + ret.put("base", UserTokenUtil.LOGIN_PROPERTIES.getSlipVerifyCount()); + ret.put("curr", slipCount); + return ResultWrapper.getSuccessResultWrapper(ret); + } + + + /** + * 登出 + */ + @Limiter + @ApiOperation(value = "登出", notes = "登出") + @PostMapping("/system/logout") + public ResultWrapper logout(HttpServletRequest request) { + String token = UserContextHolder.getToken().orElseThrow(() -> new TokenException( + TokenMsg.AUTH_CREDENTIALS_INVALID)); + + LoginUserDto loginUserDto = UserTokenUtil.getLoginUserDto(token) + .orElseThrow(() -> new TokenException(TokenMsg.AUTH_CREDENTIALS_INVALID)); + + UserModel userModel = UserUtil.getUserByUserName(loginUserDto.getUsername()); + if(null == userModel){ + return ResultWrapper.getErrorResultWrapper(); + } + + // 异步记录信息 + LoginLogsModel userLoginModel = UserLoginLogFactory + .getUserLoginModel(request, userModel, false); + userLoginModel.setLoginFrom(loginUserDto.getLoginFrom()); + + springSecurityEventBus.post(userLoginModel); + + UserTokenUtil.logout(token); + + return ResultWrapper + .getSuccessResultWrapperByMsg( + TokenMsg.EXCEPTION_LOGOUT_SUCCESS.getMessage()); + } + +} 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 deleted file mode 100644 index 34cfa18..0000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java +++ /dev/null @@ -1,280 +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.modulars.system.login.web; - -import cn.hutool.core.collection.CollUtil; -import com.google.common.collect.Maps; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.opsli.api.base.result.ResultVo; -import org.opsli.api.wrapper.system.logs.LoginLogsModel; -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.Limiter; -import org.opsli.common.annotation.LoginCrypto; -import org.opsli.common.enums.AlertType; -import org.opsli.common.enums.DictType; -import org.opsli.common.enums.OptionsType; -import org.opsli.common.exception.TokenException; -import org.opsli.common.thread.AsyncProcessExecutor; -import org.opsli.common.thread.AsyncProcessExecutorFactory; -import org.opsli.common.utils.IPUtil; -import org.opsli.core.holder.UserContextHolder; -import org.opsli.core.msg.TokenMsg; -import org.opsli.core.utils.*; -import org.opsli.modulars.system.login.entity.LoginForm; -import org.opsli.modulars.system.logs.factory.UserLoginLogFactory; -import org.opsli.modulars.system.logs.service.ILoginLogsService; -import org.opsli.modulars.system.user.service.IUserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -/** - * 登陆 / 登出 / 验证码 - * 不需要继承 api 接口 - * - * @author parker - * @date 2020-05-23 13:30 - */ -@Api(tags = "登录相关") -@Slf4j -@RestController -public class LoginRestController { - - @Autowired - private IUserService iUserService; - @Autowired - private ILoginLogsService iLoginLogsService; - - /** - * 登录 登录数据加密 - */ - @Limiter - @LoginCrypto - @ApiOperation(value = "登录", notes = "登录") - @PostMapping("/system/login") - public ResultVo login(@RequestBody LoginForm form, HttpServletRequest request){ - - // 非空验证 - if(form == null){ - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_NULL); - } - - // 验证登录对象 - ValidatorUtil.verify(form); - - // 判断账号是否临时锁定 - UserTokenUtil.verifyLockAccount(form.getUsername()); - - // 获得当前失败次数 - long slipCount = UserTokenUtil.getSlipCount(form.getUsername()); - - // 失败次数超过 验证次数阈值 开启验证码验证 - if(slipCount >= UserTokenUtil.LOGIN_PROPERTIES.getSlipVerifyCount()){ - CaptchaUtil.validate(form.getUuid(), form.getCaptcha()); - } - - // 用户信息 - UserModel user = UserUtil.getUserByUserName(form.getUsername()); - - // 账号不存在、密码错误 - if(user == null || - !user.getPassword().equals(UserUtil.handlePassword(form.getPassword(), user.getSecretKey()))) { - // 判断是否需要锁定账号 这里没有直接抛异常 而是返回错误信息, 其中包含 是否开启验证码状态 - TokenMsg lockAccountMsg = UserTokenUtil.lockAccount(form.getUsername()); - throw new TokenException(lockAccountMsg); - } - - // 如果验证成功, 则清除锁定信息 - UserTokenUtil.clearLockAccount(form.getUsername()); - - // 如果不是超级管理员 则要进行安全验证 - if(!StringUtils.equals(UserUtil.SUPER_ADMIN, user.getUsername())){ - - // 如果不是 系统用户, 也就是租户用户 需要验证租户启用情况 - if(!TenantUtil.SUPER_ADMIN_TENANT_ID.equals(user.getTenantId())){ - // 验证租户是否生效 - TenantModel tenant = TenantUtil.getTenant(user.getTenantId()); - if(tenant == null){ - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_TENANT_NOT_USABLE); - } - } - - // 账号锁定验证 - if(StringUtils.isEmpty(user.getEnable()) || - DictType.NO_YES_NO.getValue().equals(user.getEnable())){ - // 账号已被锁定,请联系管理员 - throw new TokenException(TokenMsg.EXCEPTION_LOGIN_ACCOUNT_LOCKED); - } - - // 检测用户是否有角色 - List roleModelList = UserUtil.getUserRolesByUserId(user.getId()); - if(CollUtil.isEmpty(roleModelList)){ - // 用户暂无角色,请设置后登录 - throw new TokenException(TokenMsg.EXCEPTION_USER_ROLE_NOT_NULL); - } - - // 检测用户是否有角色菜单 - List menuModelList = UserUtil.getMenuListByUserId(user.getId()); - if(CollUtil.isEmpty(menuModelList)){ - // 用户暂无角色菜单,请设置后登录 - throw new TokenException(TokenMsg.EXCEPTION_USER_MENU_NOT_NULL); - } - - // 检测用户是否有角色权限 - List userAllPermsList = UserUtil.getUserAllPermsByUserId(user.getId()); - if(CollUtil.isEmpty(userAllPermsList)){ - // 用户暂无角色菜单,请设置后登录 - throw new TokenException(TokenMsg.EXCEPTION_USER_PERMS_NOT_NULL); - } - } - - // 失败次数超过 验证次数阈值 开启验证码验证 - if(slipCount >= UserTokenUtil.LOGIN_PROPERTIES.getSlipVerifyCount()){ - // 删除验证过后验证码 - CaptchaUtil.delCaptcha(form.getUuid()); - } - - //生成token,并保存到Redis - ResultVo resultVo = UserTokenUtil.createToken(user); - if(resultVo.isSuccess()){ - // 保存Token 到当前线程缓存 - UserContextHolder.setToken(resultVo.getData().getToken()); - - AsyncProcessExecutor normalExecutor = AsyncProcessExecutorFactory.createNormalExecutor(); - // 异步保存IP - normalExecutor.put(()->{ - // 保存用户最后登录IP - String clientIpAddress = IPUtil.getClientIdBySingle(request); - user.setLoginIp(clientIpAddress); - iUserService.updateLoginIp(user); - - // 记录用户登录日志 如果系统较大 可考虑 Elastic 的 filebeat - // 小系统 直接存在 mysql就好 - LoginLogsModel userLoginModel = UserLoginLogFactory.getUserLoginModel(request, user, true); - iLoginLogsService.insert(userLoginModel); - }); - normalExecutor.execute(); - } - return resultVo; - } - - - /** - * 登出 - */ - @Limiter - @ApiOperation(value = "登出", notes = "登出") - @PostMapping("/system/logout") - public ResultVo logout(HttpServletRequest request) { - String token = UserContextHolder.getToken().orElseThrow(() -> new TokenException( - TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY)); - - // 登出失败,没有授权Token - if(StringUtils.isEmpty(token)){ - return ResultVo.error(TokenMsg.EXCEPTION_LOGOUT_ERROR.getMessage()); - } - - // 异步记录信息 - AsyncProcessExecutor normalExecutor = AsyncProcessExecutorFactory.createNormalExecutor(); - UserModel user = UserUtil.getUser(); - normalExecutor.put(()->{ - // 记录用户登录日志 如果系统较大 可考虑 Elastic 的 filebeat - // 小系统 直接存在 mysql就好 - LoginLogsModel userLoginModel = UserLoginLogFactory.getUserLoginModel(request, user, false); - iLoginLogsService.insert(userLoginModel); - }); - normalExecutor.execute(); - - UserTokenUtil.logout(token); - return ResultVo.success(TokenMsg.EXCEPTION_LOGOUT_SUCCESS.getMessage()); - } - - /** - * 获得当前登录失败次数 - */ - @Limiter - @ApiOperation(value = "获得当前登录失败次数", notes = "获得当前登录失败次数") - @GetMapping("/system/slipCount") - public ResultVo slipCount(String username){ - // 获得当前失败次数 - long slipCount = UserTokenUtil.getSlipCount(username); - Map ret = Maps.newHashMap(); - ret.put("base", UserTokenUtil.LOGIN_PROPERTIES.getSlipVerifyCount()); - ret.put("curr", slipCount); - return ResultVo.success(ret); - } - - - /** - * 验证码 - */ - @Limiter(alertType = AlertType.ALERT) - @ApiOperation(value = "验证码", notes = "验证码") - @GetMapping("captcha") - public void captcha(String uuid, HttpServletResponse response) throws IOException { - ServletOutputStream out = response.getOutputStream(); - if(out != null){ - response.setHeader("Cache-Control", "no-store, no-cache"); - //生成图片验证码 - CaptchaUtil.createCaptcha(uuid, out); - } - } - - /** - * 获得公钥 - */ - @Limiter - @ApiOperation(value = "获得公钥", notes = "获得公钥") - @GetMapping("/system/publicKey") - public ResultVo getPublicKey(){ - - // 获得公钥 - OptionsModel option = OptionsUtil.getOptionByCode(OptionsType.CRYPTO_ASYMMETRIC_PUBLIC_KEY); - if(option != null){ - return ResultVo.success( - "操作成功!", - option.getOptionValue() - ); - } - - // 失败 - return ResultVo.error(); - } - - // ================= - - public static void main(String[] args) { - String passwordStr = "Bb123456"; - String password = UserUtil.handlePassword(passwordStr, "z25fk1otoj45ref83shq"); - System.out.println(password); - } -} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/OperationLog.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/OperationLog.java new file mode 100755 index 0000000..2f766d1 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/OperationLog.java @@ -0,0 +1,75 @@ +/** + * 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.modulars.system.logs.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.opsli.core.base.entity.BaseEntity; + +/** + * 行为日志 Entity + * + * @author Parker + * @date 2022-07-26 19:21:57 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class OperationLog extends BaseEntity { + + /** 多租户字段 */ + private String tenantId; + + /** 日志等级 */ + private String level; + + /** 被操作的系统模块 */ + private String moduleId; + + /** 方法名 */ + private String method; + + /** 参数 */ + private String args; + + /** 操作人id */ + private String userId; + + /** 操作账号 */ + private String username; + + /** 真实姓名 */ + private String realName; + + /** 日志描述 */ + private String description; + + /** 操作类型 */ + private String operationType; + + /** 方法运行时间 */ + private String runTime; + + /** 方法返回值 */ + private String returnValue; + + /** 日志请求类型 */ + private String logType; + + + // ======================================== + + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/SysLoginLogs.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/SysLoginLogs.java index 844bb19..1c41b4b 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/SysLoginLogs.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/entity/SysLoginLogs.java @@ -22,30 +22,24 @@ import org.opsli.core.base.entity.BaseEntity; /** * 登录日志信息 * - * @author 周鹏程 + * @author Parker * @date 2022年3月18日17:45:18 */ @Data @EqualsAndHashCode(callSuper = false) public class SysLoginLogs extends BaseEntity { - - /** - * 多租户字段 - */ + /** 多租户字段 */ private String tenantId; /** * 组织机构ID组 xxx,xxx */ private String orgIds; - /** - * 用户名称 - */ + /** 用户名称 */ private String username; - /** - * 真实姓名 - */ + + /** 真实姓名 */ private String realName; /** @@ -55,13 +49,13 @@ public class SysLoginLogs extends BaseEntity { */ private String type; - /** - * 操作IP地址 - */ + /** 操作IP地址 */ private String remoteAddr; - /** - * 用户代理 - */ + + /** 用户代理 */ private String userAgent; + /** 登陆来源 */ + private String loginFrom; + } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/event/LoginLogEvent.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/event/LoginLogEvent.java new file mode 100644 index 0000000..fea40ab --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/event/LoginLogEvent.java @@ -0,0 +1,61 @@ +/** + * 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.modulars.system.logs.event; + +import com.google.common.eventbus.Subscribe; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.wrapper.system.logs.LoginLogsModel; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.core.utils.UserUtil; +import org.opsli.modulars.system.logs.service.ILoginLogsService; +import org.opsli.modulars.system.user.service.IUserService; +import org.opsli.plugins.security.eventbus.ISecurityEventConsumer; +import org.springframework.stereotype.Component; + +/** + * 记录登陆日志信息 + * + * @author Parker + * @date 2022-07-20 10:37:58 + */ +@Slf4j +@AllArgsConstructor +@Component +public class LoginLogEvent implements ISecurityEventConsumer { + + private final IUserService iUserService; + private final ILoginLogsService iLoginLogsService; + + @Override + @Subscribe + public void consumer(LoginLogsModel userLoginModel) { + //log.info("登陆用户信息 => {}", userLoginModel); + UserModel userModel = UserUtil.getUserByUserName(userLoginModel.getUsername()); + if(null == userModel){ + return; + } + + // 保存用户最后登录IP + userModel.setLoginIp(userLoginModel.getRemoteAddr()); + iUserService.updateLoginIp(userModel); + + // 记录用户登录日志 如果系统较大 可考虑 Elastic 的 filebeat + // 小系统 直接存在 mysql就好 + iLoginLogsService.insert(userLoginModel); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/event/OperationLogEvent.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/event/OperationLogEvent.java new file mode 100644 index 0000000..9da0737 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/event/OperationLogEvent.java @@ -0,0 +1,51 @@ +/** + * 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.modulars.system.logs.event; + +import com.google.common.eventbus.Subscribe; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.wrapper.system.logs.OperationLogModel; +import org.opsli.common.utils.WrapperUtil; +import org.opsli.core.eventbus.IEventConsumer; +import org.opsli.core.log.bean.OperationLog; +import org.opsli.modulars.system.logs.service.IOperationLogService; +import org.springframework.stereotype.Component; + +/** + * 操作日志 事件 + * + * @author Parker + * @date 2021年7月15日20:28:24 + */ +@Slf4j +@AllArgsConstructor +@Component +public class OperationLogEvent implements IEventConsumer { + + private final IOperationLogService operationLogService; + + @Subscribe + @Override + public void consumer(OperationLog event) { + //log.info("存储日志:{}", event); + OperationLogModel operationLogModel = + WrapperUtil.transformInstance(event, OperationLogModel.class); + operationLogModel.setId(null); + operationLogService.save(operationLogModel); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/factory/UserLoginLogFactory.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/factory/UserLoginLogFactory.java index b99dfc3..a99d795 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/factory/UserLoginLogFactory.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/factory/UserLoginLogFactory.java @@ -11,7 +11,7 @@ import org.springframework.util.ObjectUtils; import javax.servlet.http.HttpServletRequest; /** - * @author 周鹏程 + * @author Parker * @date 2022/3/18 14:34 */ public final class UserLoginLogFactory { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/mapper/OperationLogMapper.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/mapper/OperationLogMapper.java new file mode 100755 index 0000000..46e6378 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/mapper/OperationLogMapper.java @@ -0,0 +1,32 @@ +/** + * 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.modulars.system.logs.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.opsli.modulars.system.logs.entity.OperationLog; + +/** + * 行为日志 Mapper + * + * @author Parker + * @date 2022-07-26 19:21:57 + */ +@Mapper +public interface OperationLogMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/mapper/xml/OperationLogMapper.xml b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/mapper/xml/OperationLogMapper.xml new file mode 100755 index 0000000..e128841 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/mapper/xml/OperationLogMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/IOperationLogService.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/IOperationLogService.java new file mode 100755 index 0000000..5b3830c --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/IOperationLogService.java @@ -0,0 +1,32 @@ +/** + * 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.modulars.system.logs.service; + +import org.opsli.core.base.service.interfaces.CrudServiceInterface; + + +import org.opsli.modulars.system.logs.entity.OperationLog; +import org.opsli.api.wrapper.system.logs.OperationLogModel; + +/** + * 行为日志 Service + * + * @author Parker + * @date 2022-07-26 19:21:57 + */ +public interface IOperationLogService extends CrudServiceInterface { + +} \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/LogsServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/LogsServiceImpl.java index 06529e2..e44050a 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/LogsServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/LogsServiceImpl.java @@ -46,7 +46,7 @@ public class LogsServiceImpl extends CrudServiceImpl LOG_BIG_COUNT){ this.emptyByOneMonth(); diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/OperationLogServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/OperationLogServiceImpl.java new file mode 100755 index 0000000..ca9a637 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/service/impl/OperationLogServiceImpl.java @@ -0,0 +1,43 @@ +/** + * 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.modulars.system.logs.service.impl; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.opsli.core.base.service.impl.CrudServiceImpl; + +import org.opsli.modulars.system.logs.entity.OperationLog; +import org.opsli.api.wrapper.system.logs.OperationLogModel; +import org.opsli.modulars.system.logs.service.IOperationLogService; +import org.opsli.modulars.system.logs.mapper.OperationLogMapper; + + +/** + * 行为日志 Service Impl + * + * @author Parker + * @date 2022-07-26 19:21:57 + */ +@Service +public class OperationLogServiceImpl extends CrudServiceImpl + implements IOperationLogService { + + @Autowired(required = false) + private OperationLogMapper mapper; + +} \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LoginLogsRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LoginLogsRestController.java index 6188f6d..dd16d3d 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LoginLogsRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/LoginLogsRestController.java @@ -18,14 +18,14 @@ package org.opsli.modulars.system.logs.web; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.springframework.security.access.prepost.PreAuthorize; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.logs.LoginLogsApi; import org.opsli.api.web.system.logs.LogsApi; import org.opsli.api.wrapper.system.logs.LoginLogsModel; import org.opsli.api.wrapper.system.logs.LogsModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; + import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; @@ -55,19 +55,19 @@ public class LoginLogsRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } } 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 98ecb4c..236d63d 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 @@ -18,12 +18,12 @@ package org.opsli.modulars.system.logs.web; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.springframework.security.access.prepost.PreAuthorize; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.logs.LogsApi; import org.opsli.api.wrapper.system.logs.LogsModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; + import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; @@ -50,14 +50,14 @@ public class LogsRestController extends BaseRestController get(LogsModel model) { + public ResultWrapper get(LogsModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -65,25 +65,25 @@ public class LogsRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } @Override - public ResultVo insert(LogsModel model) { + public ResultWrapper insert(LogsModel model) { IService.insert(model); - return ResultVo.success("新增日志成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增日志成功"); } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/OperationLogRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/OperationLogRestController.java new file mode 100755 index 0000000..fcf4bc5 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/logs/web/OperationLogRestController.java @@ -0,0 +1,122 @@ +/** + * 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.modulars.system.logs.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.web.system.logs.OperationLogRestApi; +import org.opsli.api.wrapper.system.logs.OperationLogModel; +import org.opsli.common.annotation.ApiRestController; +import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; +import org.opsli.core.persistence.Page; +import org.opsli.core.persistence.querybuilder.QueryBuilder; +import org.opsli.core.persistence.querybuilder.WebQueryBuilder; +import org.opsli.modulars.system.logs.entity.OperationLog; +import org.opsli.modulars.system.logs.service.IOperationLogService; +import org.springframework.security.access.prepost.PreAuthorize; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Optional; + +/** + * 行为日志 Controller + * + * @author Parker + * @date 2022-07-26 19:21:57 + */ +@Api(tags = OperationLogRestApi.TITLE) +@Slf4j +@ApiRestController("/{ver}/system/op-logs") +public class OperationLogRestController extends BaseRestController + implements OperationLogRestApi { + + + /** + * 行为日志 查一条 + * @param model 模型 + * @return ResultVo + */ + @ApiOperation(value = "获得单条行为日志", notes = "获得单条行为日志 - ID") + @PreAuthorize("hasAuthority('system_op_logs_select')") + @Override + public ResultWrapper get(OperationLogModel model) { + // 如果系统内部调用 则直接查数据库 + if(model != null && model.getIzApi() != null && model.getIzApi()){ + model = IService.get(model); + } + return ResultWrapper.getSuccessResultWrapper(model); + } + + /** + * 行为日志 查询分页 + * @param pageNo 当前页 + * @param pageSize 每页条数 + * @param request request + * @return ResultVo + */ + @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器") + @PreAuthorize("hasAuthority('system_op_logs_select')") + @Override + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + page.setQueryWrapper(queryBuilder.build()); + page = IService.findPage(page); + + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); + } + + /** + * 行为日志 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAuthority('system_op_logs_export')") + @Override + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, OperationLogRestApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } + + + /** + * 行为日志 Excel 导出 + * @param response response + */ + @ApiOperation(value = "导出Excel", notes = "导出Excel") + @PreAuthorize("hasAuthority('system_op_logs_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_OPERATION, operationType = OperationTypeEnum.SELECT, db = true) + @Override + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/factory/MenuFactory.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/factory/MenuFactory.java index d7ffc09..8ed8aaf 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/factory/MenuFactory.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/factory/MenuFactory.java @@ -14,7 +14,7 @@ import java.util.List; /** * 菜单生成工厂 * - * @author 周鹏程 + * @author Parker * @date 2021-05-04 7:15 **/ public enum MenuFactory { 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 895c6be..78829ca 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 @@ -21,7 +21,6 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; -import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -29,15 +28,12 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.menu.MenuApi; import org.opsli.api.wrapper.system.menu.MenuFullModel; import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.constants.MenuConstants; import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.enums.DictType; @@ -45,6 +41,9 @@ import org.opsli.common.utils.FieldUtil; import org.opsli.common.utils.WrapperUtil; import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.general.StartPrint; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder; @@ -54,13 +53,10 @@ import org.opsli.core.utils.UserUtil; import org.opsli.modulars.system.menu.entity.SysMenu; import org.opsli.modulars.system.menu.service.IMenuService; import org.opsli.modulars.system.user.service.IUserRoleRefService; -import org.opsli.modulars.system.user.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.security.access.prepost.PreAuthorize; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; import java.util.List; import java.util.Map; @@ -97,11 +93,11 @@ public class MenuRestController extends BaseRestController getMenuAndPermsTree(String label) { + public ResultWrapper getMenuAndPermsTree(String label) { UserModel user = UserUtil.getUser(); // 获得当前用户菜单 @@ -118,7 +114,7 @@ public class MenuRestController extends BaseRestController> treeNodes = getMenuTrees(menuModelList); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } /** @@ -126,11 +122,11 @@ public class MenuRestController extends BaseRestController findMenuTree() { + public ResultWrapper findMenuTree() { UserModel user = UserUtil.getUser(); // 获得用户 对应菜单 @@ -147,7 +143,7 @@ public class MenuRestController extends BaseRestController> treeNodes = getMenuTrees(menuModelList, EXCLUSION_FIELDS); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } @@ -155,12 +151,12 @@ public class MenuRestController extends BaseRestController findMenuTreeByLazy(String parentId, String id) { + public ResultWrapper findMenuTreeByLazy(String parentId, String id) { List menuModelList; if(StringUtils.isEmpty(parentId)){ menuModelList = Lists.newArrayList(); @@ -195,19 +191,19 @@ public class MenuRestController extends BaseRestController IService.hasChildrenByChoose(parentIds)); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } /** * 获得列表菜单树 懒加载 * * @param parentId 父节点ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得列表菜单树 懒加载", notes = "获得列表菜单树 懒加载") - @RequiresPermissions("system_menu_select") + @PreAuthorize("hasAuthority('system_menu_select')") @Override - public ResultVo findMenuTreePageByLazy(String parentId) { + public ResultWrapper findMenuTreePageByLazy(String parentId) { List menuModelList; if(StringUtils.isEmpty(parentId)){ menuModelList = Lists.newArrayList(); @@ -231,18 +227,18 @@ public class MenuRestController extends BaseRestController IService.hasChildren(parentIds)); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } /** * 获得列表菜单树 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得列表菜单树", notes = "获得列表菜单树") - @RequiresPermissions("system_menu_select") + @PreAuthorize("hasAuthority('system_menu_select')") @Override - public ResultVo findMenuTreePage(HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, + public ResultWrapper findMenuTreePage(HttpServletRequest request) { + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); // 获得菜单 @@ -252,33 +248,33 @@ public class MenuRestController extends BaseRestController> treeNodes = getMenuTrees(menuModelList); - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } /** * 获得菜单List - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得菜单List", notes = "获得菜单List") - @RequiresPermissions("system_menu_select") + @PreAuthorize("hasAuthority('system_menu_select')") @Override - public ResultVo> findList() { + public ResultWrapper> findList() { QueryBuilder queryBuilder = new GenQueryBuilder<>(); // 菜单集合 List menuList = IService.findList(queryBuilder.build()); - List menuModelList = WrapperUtil.transformInstance(menuList, modelClazz); - return ResultVo.success(menuModelList); + List menuModelList = WrapperUtil.transformInstance(menuList, IService.getModelClass()); + return ResultWrapper.getSuccessResultWrapper(menuModelList); } /** * 菜单 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得单条菜单", notes = "获得单条菜单 - ID") - @RequiresPermissions("system_menu_select") + @PreAuthorize("hasAuthority('system_menu_select')") @Override - public ResultVo get(MenuModel model) { + public ResultWrapper get(MenuModel model) { if(model != null){ if(StringUtils.equals(MenuConstants.GEN_ID, model.getId())){ // 生成根节点菜单 @@ -288,7 +284,7 @@ public class MenuRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 菜单 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增菜单", notes = "新增菜单") - @RequiresPermissions("system_menu_insert") - @EnableLog + @PreAuthorize("hasAuthority('system_menu_insert')") + @OperateLogger(description = "新增菜单", + module = ModuleEnum.MODULE_MENU, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(MenuModel model) { + public ResultWrapper insert(MenuModel model) { // 演示模式 不允许操作 super.demoError(); // 调用新增方法 IService.insert(model); - return ResultVo.success("新增菜单成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增菜单成功"); } /** * 菜单 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改菜单", notes = "修改菜单") - @RequiresPermissions("system_menu_update") - @EnableLog + @PreAuthorize("hasAuthority('system_menu_update')") + @OperateLogger(description = "修改菜单", + module = ModuleEnum.MODULE_MENU, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(MenuModel model) { + public ResultWrapper update(MenuModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改菜单成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改菜单成功"); } /** * 菜单 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除菜单数据", notes = "删除菜单数据") - @RequiresPermissions("system_menu_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_menu_delete')") + @OperateLogger(description = "删除菜单数据", + module = ModuleEnum.MODULE_MENU, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 演示模式 不允许操作 super.demoError(); IService.delete(id); - return ResultVo.success("删除菜单成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除菜单成功"); } /** * 菜单 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除菜单数据", notes = "批量删除菜单数据") - @RequiresPermissions("system_menu_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_menu_delete')") + @OperateLogger(description = "批量删除菜单数据", + module = ModuleEnum.MODULE_MENU, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 演示模式 不允许操作 super.demoError(); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除菜单成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除菜单成功"); } - /** - * 菜单 Excel 导出 - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_menu_export") - @EnableLog - @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(MenuApi.SUB_TITLE, queryBuilder.build(), response, method); - } - - /** - * 菜单 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_menu_import") - @EnableLog - @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); - } - - /** - * 菜单 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_menu_import") - @EnableLog - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(MenuApi.SUB_TITLE, response, method); - } - // ================== /** * 根据菜单权限 获得菜单 * @param permissions 菜单权限 - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo getByPermissions(String permissions) { + public ResultWrapper getByPermissions(String permissions) { MenuModel menu = IService.getByPermissions(permissions); if(menu == null){ - ResultVo.error("暂无数据"); + ResultWrapper.getErrorResultWrapper().setMsg("暂无数据"); } - return ResultVo.success(menu); + return ResultWrapper.getSuccessResultWrapper(menu); } @@ -590,11 +547,11 @@ public class MenuRestController extends BaseRestController saveMenuByFull(MenuFullModel menuFullModel) { + public ResultWrapper saveMenuByFull(MenuFullModel menuFullModel) { IService.saveMenuByFull(menuFullModel); - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } } 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 b701790..d2561d7 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 @@ -19,8 +19,8 @@ import com.google.common.collect.Maps; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.springframework.security.access.prepost.PreAuthorize; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; import org.opsli.core.utils.SystemInfoUtil; import org.springframework.web.bind.annotation.GetMapping; @@ -40,12 +40,12 @@ public class MonitorController { /** * 查询服务器信息 - * @return ResultVo + * @return ResultWrapper */ - @RequiresPermissions("devops_sysmonitor_select") + @PreAuthorize("hasAuthority('devops_sysmonitor_select')") @GetMapping("/getSystemInfo") @ApiOperation(value = "当前服务器信息", notes = "当前服务器信息") - public ResultVo getSystemInfo() { + public ResultWrapper getSystemInfo() { Map map = Maps.newHashMapWithExpectedSize(5); //服务器信息 map.put("systemInfo", SystemInfoUtil.INSTANCE.getSysInfo()); @@ -57,42 +57,42 @@ public class MonitorController { map.put("JVMInfo", SystemInfoUtil.INSTANCE.getJvmInfo()); //磁盘信息 map.put("sysFileInfo", SystemInfoUtil.INSTANCE.getDiskInfo()); - return ResultVo.success(map); + return ResultWrapper.getSuccessResultWrapper(map); } /** * 查询CPU信息 - * @return ResultVo + * @return ResultWrapper */ - @RequiresPermissions("devops_sysmonitor_select") + @PreAuthorize("hasAuthority('devops_sysmonitor_select')") @GetMapping("/getCpuInfo") @ApiOperation(value = "当前CPU信息", notes = "当前CPU信息") - public ResultVo getCpuInfo() { - return ResultVo.success( - SystemInfoUtil.INSTANCE.getCpuInfo()); + public ResultWrapper getCpuInfo() { + return ResultWrapper + .getSuccessResultWrapper(SystemInfoUtil.INSTANCE.getCpuInfo()); } /** * 查询内存信息 - * @return ResultVo + * @return ResultWrapper */ - @RequiresPermissions("devops_sysmonitor_select") + @PreAuthorize("hasAuthority('devops_sysmonitor_select')") @GetMapping("/getMemInfo") @ApiOperation(value = "当前内存信息", notes = "当前内存信息") - public ResultVo getMemInfo() { - return ResultVo.success( + public ResultWrapper getMemInfo() { + return ResultWrapper.getSuccessResultWrapper( SystemInfoUtil.INSTANCE.getMemoryInfo()); } /** * 查询JVM信息 - * @return ResultVo + * @return ResultWrapper */ - @RequiresPermissions("devops_sysmonitor_select") + @PreAuthorize("hasAuthority('devops_sysmonitor_select')") @GetMapping("/getJVMInfo") @ApiOperation(value = "当前JVM信息", notes = "当前JVM信息") - public ResultVo getJvmInfo() { - return ResultVo.success( + public ResultWrapper getJvmInfo() { + return ResultWrapper.getSuccessResultWrapper( SystemInfoUtil.INSTANCE.getJvmInfo()); } 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 cf014c3..bf79e70 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 @@ -18,7 +18,6 @@ package org.opsli.modulars.system.options.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -27,29 +26,30 @@ import opsli.plugins.crypto.CryptoPlugin; import opsli.plugins.crypto.enums.CryptoAsymmetricType; import opsli.plugins.crypto.model.CryptoAsymmetric; import opsli.plugins.crypto.strategy.CryptoAsymmetricService; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.options.OptionsApi; import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.enums.DictType; import org.opsli.common.utils.WrapperUtil; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.core.utils.OptionsUtil; import org.opsli.modulars.system.options.entity.SysOptions; import org.opsli.modulars.system.options.service.ISysOptionsService; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; import java.util.List; import java.util.Map; +import java.util.Optional; /** @@ -68,14 +68,14 @@ public class SysOptionsRestController extends BaseRestController get(OptionsModel model) { + public ResultWrapper get(OptionsModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -83,14 +83,14 @@ public class SysOptionsRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); // 查询不是内置的数据 QueryWrapper queryWrapper = queryBuilder.build(); @@ -100,152 +100,153 @@ public class SysOptionsRestController extends BaseRestController insert(OptionsModel model) { + public ResultWrapper insert(OptionsModel model) { // 演示模式 不允许操作 super.demoError(); // 调用新增方法 IService.insert(model); - return ResultVo.success("新增系统参数成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增系统参数成功"); } /** * 系统参数 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改系统参数数据", notes = "修改系统参数数据") - @RequiresPermissions("system_options_update") - @EnableLog + @PreAuthorize("hasAuthority('system_options_update')") + @OperateLogger(description = "修改系统参数数据", + module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(OptionsModel model) { + public ResultWrapper update(OptionsModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改系统参数成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改系统参数成功"); } /** * 系统参数 修改 * @param params Map - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改系统参数数据", notes = "修改系统参数数据") - @RequiresPermissions("system_options_update") - @EnableLog + @PreAuthorize("hasAuthority('system_options_update')") + @OperateLogger(description = "修改系统参数数据", + module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo updateOptions(Map params) { + public ResultWrapper updateOptions(Map params) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.updateOptions(params); - return ResultVo.success("保存参数成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("保存参数成功"); } /** * 系统参数 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除系统参数数据", notes = "删除系统参数数据") - @RequiresPermissions("system_options_update") - @EnableLog + @PreAuthorize("hasAuthority('system_options_update')") + @OperateLogger(description = "删除系统参数数据", + module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 演示模式 不允许操作 super.demoError(); IService.delete(id); - return ResultVo.success("删除系统参数成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除系统参数成功"); } /** * 系统参数 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除系统参数数据", notes = "批量删除系统参数数据") - @RequiresPermissions("system_options_update") - @EnableLog + @PreAuthorize("hasAuthority('system_options_update')") + @OperateLogger(description = "批量删除系统参数数据", + module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 演示模式 不允许操作 super.demoError(); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除系统参数成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除系统参数成功"); + } + + /** + * 系统参数 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('system_options_export', 'system_options_import')") + @Override + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, OptionsApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); } /** - * 系统参数 Excel 导出 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ + * 系统参数 Excel 导出 + * @param response response + */ @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_options_export") - @EnableLog + @PreAuthorize("hasAuthority('system_options_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.SELECT, db = true) @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(OptionsApi.SUB_TITLE, queryBuilder.build(), response, method); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } + /** * 系统参数 Excel 导入 * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_options_import") - @EnableLog + @PreAuthorize("hasAuthority('system_options_import')") + @OperateLogger(description = "系统参数 Excel 导入", + module = ModuleEnum.MODULE_COMMON, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { return super.importExcel(request); } - /** - * 系统参数 Excel 下载导入模版 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_options_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(OptionsApi.SUB_TITLE, response, method); - } // ========================= @@ -254,29 +255,29 @@ public class SysOptionsRestController extends BaseRestController getByCode(String optionCode) { + public ResultWrapper getByCode(String optionCode) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("option_code", optionCode); SysOptions option = IService.getOne(wrapper); - return ResultVo.success( + return ResultWrapper.getSuccessResultWrapper( WrapperUtil.transformInstance(option, OptionsModel.class) ); } /** * 系统参数 查询全部 - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo> findAllOptions() { + public ResultWrapper> findAllOptions() { QueryWrapper queryWrapper = new QueryWrapper<>(); // 查询内置数据 queryWrapper.eq("iz_lock", DictType.NO_YES_YES.getValue()); // 数据库查询数据 List allList = IService.findList(queryWrapper); - return ResultVo.success( + return ResultWrapper.getSuccessResultWrapper( OptionsUtil.convertOptionsMap( WrapperUtil.transformInstance(allList, OptionsModel.class)) ); @@ -284,11 +285,11 @@ public class SysOptionsRestController extends BaseRestController> findAll() { - return ResultVo.success( + public ResultWrapper> findAll() { + return ResultWrapper.getSuccessResultWrapper( WrapperUtil.transformInstance(IService.findAllList(), OptionsModel.class) ); } @@ -296,20 +297,20 @@ public class SysOptionsRestController extends BaseRestController createCrypto(String type) { + @PreAuthorize("hasAuthority('system_options_update')") + public ResultWrapper createCrypto(String type) { CryptoAsymmetricType cryptoType = CryptoAsymmetricType.getCryptoType(type); if(cryptoType == null){ - return ResultVo.error(); + return ResultWrapper.getErrorResultWrapper(); } CryptoAsymmetricService asymmetricService = CryptoPlugin.getAsymmetric(); CryptoAsymmetric keyModel = asymmetricService.createKeyModel(cryptoType); - return ResultVo.success( + return ResultWrapper.getSuccessResultWrapper( keyModel ); } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/service/impl/SysOrgServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/service/impl/SysOrgServiceImpl.java index 68c7836..89e983a 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/service/impl/SysOrgServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/org/service/impl/SysOrgServiceImpl.java @@ -357,7 +357,7 @@ public class SysOrgServiceImpl extends CrudServiceImpl findTreeByDefWithUserToLike() { + public ResultWrapper findTreeByDefWithUserToLike() { // 生成 全部/未分组 String parentId = PARENT_ID; List orgModelList = OrgUtil.createDefShowNodes(parentId, Lists.newArrayList()); @@ -143,7 +137,7 @@ public class SysOrgRestController extends BaseRestController findTreeLazy(String parentId, String id) { + public ResultWrapper findTreeLazy(String parentId, String id) { List orgModelList; if(StringUtils.isEmpty(parentId)){ orgModelList = Lists.newArrayList(); @@ -204,7 +198,7 @@ public class SysOrgRestController extends BaseRestController findTreeByDef(boolean isGen, String id) { + public ResultWrapper findTreeByDef(boolean isGen, String id) { List orgModelList = Lists.newArrayList(); String parentId = PARENT_ID; if(isGen){ @@ -284,7 +278,7 @@ public class SysOrgRestController extends BaseRestController get(SysOrgModel model) { + public ResultWrapper get(SysOrgModel model) { if(model != null){ if(StringUtils.equals(PARENT_ID, model.getId())){ // 生成根节点组织 @@ -315,19 +309,20 @@ public class SysOrgRestController extends BaseRestController insert(SysOrgModel model) { + public ResultWrapper insert(SysOrgModel model) { // 如果新增的是 根节点数据 则需要验证权限 if(null != model && TreeBuildUtil.DEF_PARENT_ID.equals(model.getParentId())){ @@ -349,107 +344,68 @@ public class SysOrgRestController extends BaseRestController update(SysOrgModel model) { + public ResultWrapper update(SysOrgModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改组织机构成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改组织机构成功"); } /** * 组织机构 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除组织机构数据", notes = "删除组织机构数据") - @RequiresPermissions("system_org_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_org_delete')") + @OperateLogger(description = "删除组织机构数据", + module = ModuleEnum.MODULE_ORG, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 演示模式 不允许操作 super.demoError(); IService.delete(id); - return ResultVo.success("删除组织机构成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除组织机构成功"); } /** * 组织机构 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除组织机构数据", notes = "批量删除组织机构数据") - @RequiresPermissions("system_org_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_org_delete')") + @OperateLogger(description = "批量删除组织机构数据", + module = ModuleEnum.MODULE_ORG, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 演示模式 不允许操作 super.demoError(); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除组织机构成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除组织机构成功"); } - /** - * 组织机构 Excel 导出 - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_org_export") - @EnableLog - @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(SysOrgRestApi.SUB_TITLE, queryBuilder.build(), response, method); - } - - /** - * 组织机构 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_org_import") - @EnableLog - @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); - } - - /** - * 组织机构 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_org_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(SysOrgRestApi.SUB_TITLE, response, method); - } - // ============================== /** @@ -472,9 +428,9 @@ public class SysOrgRestController extends BaseRestController handleOrgTree(String parentId, List orgModelList, boolean izLazy) { + private ResultWrapper handleOrgTree(String parentId, List orgModelList, boolean izLazy) { //配置 TreeNodeConfig treeNodeConfig = new TreeNodeConfig(); // 自定义属性名 都要默认值的 @@ -507,7 +463,7 @@ public class SysOrgRestController extends BaseRestController IService.hasChildren(parentIdSet)); } - return ResultVo.success(treeNodes); + return ResultWrapper.getSuccessResultWrapper(treeNodes); } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java index 14c6b90..220c3a1 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/role/service/impl/RoleServiceImpl.java @@ -199,7 +199,7 @@ public class RoleServiceImpl extends CrudServiceImpl getPerms(RoleMenuRefModel model) { + public ResultWrapper getPerms(RoleMenuRefModel model) { if(model == null){ - return ResultVo.error(SystemMsg.EXCEPTION_ROLE_ID_NOT_NULL.getCode(), - SystemMsg.EXCEPTION_ROLE_ID_NOT_NULL.getMessage()); + return ResultWrapper.getCustomResultWrapper(SystemMsg.EXCEPTION_ROLE_ID_NOT_NULL); } List perms = iRoleMenuRefService.getPerms(model.getRoleId()); @@ -88,34 +90,33 @@ public class RoleMenuRefRestController implements RoleMenuRefApi { } } - return ResultVo.success(permsIds); + return ResultWrapper.getSuccessResultWrapper(permsIds); } /** * 设置菜單权限 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ - @RequiresPermissions("system_role_setMenuPerms") - @EnableLog + @PreAuthorize("hasAuthority('system_role_setMenuPerms')") + @OperateLogger(description = "设置菜單权限", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo setPerms(RoleMenuRefModel model) { + public ResultWrapper setPerms(RoleMenuRefModel model) { // 演示模式 不允许操作 this.demoError(); if(model == null){ - return ResultVo.error("设置权限失败"); + return ResultWrapper.getErrorResultWrapper().setMsg("设置权限失败"); } boolean ret = iRoleMenuRefService.setPerms(model.getRoleId(), model.getPermsIds()); if(ret){ - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } // 权限设置失败 - return ResultVo.error(SystemMsg.EXCEPTION_ROLE_PERMS_ERROR.getCode(), - SystemMsg.EXCEPTION_ROLE_PERMS_ERROR.getMessage() - ); + return ResultWrapper.getCustomResultWrapper(SystemMsg.EXCEPTION_ROLE_PERMS_ERROR); } 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 4f4638e..0a46c1a 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 @@ -16,29 +16,29 @@ package org.opsli.modulars.system.role.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.role.RoleApi; import org.opsli.api.wrapper.system.role.RoleModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.modulars.system.role.entity.SysRole; import org.opsli.modulars.system.role.service.IRoleService; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; +import java.util.Optional; /** @@ -56,14 +56,14 @@ public class RoleRestController extends BaseRestController get(RoleModel model) { + public ResultWrapper get(RoleModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -71,135 +71,145 @@ public class RoleRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); QueryWrapper wrapper = queryBuilder.build(); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(wrapper); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 角色 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增角色", notes = "新增角色") - @RequiresPermissions("system_role_insert") - @EnableLog + @PreAuthorize("hasAuthority('system_role_insert')") + @OperateLogger(description = "新增角色", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(RoleModel model) { + public ResultWrapper insert(RoleModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增角色成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增角色成功"); } /** * 角色 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改角色", notes = "修改角色") - @RequiresPermissions("system_role_update") - @EnableLog + @PreAuthorize("hasAuthority('system_role_update')") + @OperateLogger(description = "修改角色", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(RoleModel model) { + public ResultWrapper update(RoleModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改角色成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改角色成功"); } /** * 角色 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除角色数据", notes = "删除角色数据") - @RequiresPermissions("system_role_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_role_delete')") + @OperateLogger(description = "删除角色数据", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 演示模式 不允许操作 super.demoError(); IService.delete(id); - return ResultVo.success("删除角色成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除角色成功"); } /** * 角色 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除角色数据", notes = "批量删除角色数据") - @RequiresPermissions("system_role_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_role_delete')") + @OperateLogger(description = "批量删除角色数据", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 演示模式 不允许操作 super.demoError(); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除角色成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除角色成功"); } /** - * 角色 Excel 导出 + * 角色 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('system_role_export', 'system_role_import')") + @Override + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, RoleApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } + + + /** + * 角色 Excel 导出 * @param response response */ @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_role_export") - @EnableLog + @PreAuthorize("hasAuthority('system_role_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.SELECT, db = true) @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(RoleApi.SUB_TITLE, queryBuilder.build(), response, method); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } + /** * 角色 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_role_import") - @EnableLog + @PreAuthorize("hasAuthority('system_role_import')") + @OperateLogger(description = "角色 Excel 导入", + module = ModuleEnum.MODULE_ROLE, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { return super.importExcel(request); } - /** - * 角色 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_role_import") - @EnableLog - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(RoleApi.SUB_TITLE, response, method); - } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/service/impl/TenantServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/service/impl/TenantServiceImpl.java index 924ab44..b8b33b3 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/service/impl/TenantServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/tenant/service/impl/TenantServiceImpl.java @@ -353,7 +353,7 @@ public class TenantServiceImpl extends CrudServiceImpl 0){ // 该租户正在被其他用户绑定,无法删除 throw new ServiceException(SystemMsg.EXCEPTION_TENANT_USED_DEL); 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 8cbc045..355c399 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 @@ -16,32 +16,32 @@ package org.opsli.modulars.system.tenant.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.tenant.TenantApi; import org.opsli.api.wrapper.system.tenant.TenantModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.enums.DictType; import org.opsli.common.utils.WrapperUtil; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.modulars.system.tenant.entity.SysTenant; import org.opsli.modulars.system.tenant.service.ITenantService; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; +import java.util.Optional; /** @@ -59,35 +59,36 @@ public class TenantRestController extends BaseRestController enableTenant(String tenantId, String enable) { + public ResultWrapper enableTenant(String tenantId, String enable) { // 演示模式 不允许操作 super.demoError(); // 变更租户状态账户 boolean enableStatus = IService.enableTenant(tenantId, enable); if(!enableStatus){ - return ResultVo.error("变更用户状态账户失败"); + return ResultWrapper.getErrorResultWrapper().setMsg("变更租户状态账户失败"); } - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } /** * 租户 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得单条租户", notes = "获得单条租户 - ID") - @RequiresPermissions("system_tenant_select") + @PreAuthorize("hasAuthority('system_tenant_select')") @Override - public ResultVo get(TenantModel model) { + public ResultWrapper get(TenantModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -95,152 +96,162 @@ public class TenantRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 租户 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增租户", notes = "新增租户") - @RequiresPermissions("system_tenant_insert") - @EnableLog + @PreAuthorize("hasAuthority('system_tenant_insert')") + @OperateLogger(description = "新增租户", + module = ModuleEnum.MODULE_TENANT, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(TenantModel model) { + public ResultWrapper insert(TenantModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增租户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增租户成功"); } /** * 租户 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改租户", notes = "修改租户") - @RequiresPermissions("system_tenant_update") - @EnableLog + @PreAuthorize("hasAuthority('system_tenant_update')") + @OperateLogger(description = "修改租户", + module = ModuleEnum.MODULE_TENANT, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(TenantModel model) { + public ResultWrapper update(TenantModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改租户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改租户成功"); } /** * 租户 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除租户数据", notes = "删除租户数据") - @RequiresPermissions("system_tenant_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_tenant_delete')") + @OperateLogger(description = "删除租户数据", + module = ModuleEnum.MODULE_TENANT, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ // 演示模式 不允许操作 super.demoError(); IService.delete(id); - return ResultVo.success("删除租户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除租户成功"); } /** * 租户 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除租户数据", notes = "批量删除租户数据") - @RequiresPermissions("system_tenant_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_tenant_delete')") + @OperateLogger(description = "批量删除租户数据", + module = ModuleEnum.MODULE_TENANT, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ // 演示模式 不允许操作 super.demoError(); String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除租户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除租户成功"); } /** - * 租户 Excel 导出 + * 租户 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('system_tenant_export', 'system_tenant_import')") + @Override + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, TenantApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } + + + /** + * 租户 Excel 导出 * @param response response */ @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_tenant_export") - @EnableLog + @PreAuthorize("hasAuthority('system_tenant_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_TENANT, operationType = OperationTypeEnum.SELECT, db = true) @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(TenantApi.SUB_TITLE, queryBuilder.build(), response, method); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } /** * 租户 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_tenant_import") - @EnableLog + @PreAuthorize("hasAuthority('system_tenant_import')") + @OperateLogger(description = "租户 Excel 导入", + module = ModuleEnum.MODULE_TENANT, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { return super.importExcel(request); } - /** - * 租户 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_tenant_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(TenantApi.SUB_TITLE, response, method); - } // ========================= /** * 获得已启用租户 查一条 * @param tenantId 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得已启用租户", notes = "获得已启用租户 - ID") @Override - public ResultVo getTenantByUsable(String tenantId) { + public ResultWrapper getTenantByUsable(String tenantId) { QueryBuilder queryBuilder = new GenQueryBuilder<>(); QueryWrapper queryWrapper = queryBuilder.build(); queryWrapper.eq("id", tenantId) .eq("enable", DictType.NO_YES_YES.getValue()); SysTenant entity = IService.getOne(queryWrapper); - return ResultVo.success( - WrapperUtil.transformInstance(entity, modelClazz) + return ResultWrapper.getSuccessResultWrapper( + WrapperUtil.transformInstance(entity, IService.getModelClass()) ); } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/entity/SysUser.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/entity/SysUser.java index 3df08ae..eaf8e5f 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/entity/SysUser.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/entity/SysUser.java @@ -42,9 +42,6 @@ public class SysUser extends BaseEntity { /** 登录密码强度 */ private String passwordLevel; - /** 盐值,密码秘钥 */ - private String secretKey; - /** 是否启用 */ private String enable; diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserMapper.xml b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserMapper.xml index d01ea39..3008d28 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserMapper.xml +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/mapper/xml/UserMapper.xml @@ -9,7 +9,6 @@ a.username as username, a.password as password, a.password_level as passwordLevel, - a.secret_key as secretKey, a.no as no, a.real_name as realName, a.enable as enable, @@ -53,8 +52,7 @@ update sys_user set password = #{newPassword}, - password_level = #{passwordLevel}, - secret_key = #{salt} + password_level = #{passwordLevel} where id = #{userId} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/IUserService.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/IUserService.java index 923b50a..1879a84 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/IUserService.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/IUserService.java @@ -15,10 +15,7 @@ */ package org.opsli.modulars.system.user.service; -import org.opsli.api.wrapper.system.user.ToUserPassword; -import org.opsli.api.wrapper.system.user.UserModel; -import org.opsli.api.wrapper.system.user.UserPassword; -import org.opsli.api.wrapper.system.user.UserWebModel; +import org.opsli.api.wrapper.system.user.*; import org.opsli.core.base.service.interfaces.CrudServiceInterface; import org.opsli.core.persistence.Page; import org.opsli.modulars.system.user.entity.SysUser; @@ -40,6 +37,20 @@ public interface IUserService extends CrudServiceInterface { */ UserModel queryByUserName(String username); + /** + * 根据 手机号 获得当前用户 + * @param mobile 手机 + * @return UserModel + */ + UserModel queryByMobile(String mobile); + + /** + * 根据 邮箱 获得当前用户 + * @param email 邮箱 + * @return UserModel + */ + UserModel queryByEmail(String email); + /** * 修改密码 验证旧密码 @@ -55,6 +66,20 @@ public interface IUserService extends CrudServiceInterface { */ boolean updatePasswordByNotCheckOld(ToUserPassword userPassword); + /** + * 修改邮箱 + * @param updateUserEmailModel model + * @return boolean + */ + boolean updateUserEmail(UpdateUserEmailModel updateUserEmailModel); + + /** + * 修改手机 + * @param updateUserMobileModel model + * @return boolean + */ + boolean updateUserMobile(UpdateUserMobileModel updateUserMobileModel); + /** * 重置密码 * @param userPassword 账户密码 diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/impl/UserServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/impl/UserServiceImpl.java index e484005..ffd8ef7 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/impl/UserServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/user/service/impl/UserServiceImpl.java @@ -18,15 +18,20 @@ package org.opsli.modulars.system.user.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.github.pagehelper.PageInfo; import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.api.wrapper.system.user.*; import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.enums.DictType; +import org.opsli.common.enums.VerificationTypeEnum; import org.opsli.common.exception.ServiceException; import org.opsli.common.utils.CheckStrength; import org.opsli.common.utils.FieldUtil; @@ -39,6 +44,7 @@ import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.conf.WebQueryConf; import org.opsli.core.utils.OptionsUtil; import org.opsli.core.utils.UserUtil; +import org.opsli.core.utils.VerificationCodeUtil; import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.menu.service.IMenuService; import org.opsli.modulars.system.role.entity.SysRole; @@ -48,7 +54,9 @@ import org.opsli.modulars.system.user.entity.SysUserWeb; import org.opsli.modulars.system.user.mapper.UserMapper; import org.opsli.modulars.system.user.service.IUserRoleRefService; import org.opsli.modulars.system.user.service.IUserService; +import org.opsli.plugins.security.utils.PasswordUtil; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -63,17 +71,15 @@ import java.util.List; * @author Parker * @date 2020-09-16 17:33 */ +@AllArgsConstructor @Service public class UserServiceImpl extends CrudServiceImpl implements IUserService { - @Autowired(required = false) - private UserMapper mapper; - @Autowired - private IMenuService iMenuService; - @Autowired - private IRoleService iRoleService; - @Autowired - private IUserRoleRefService iUserRoleRefService; + private final UserMapper mapper; + private final IRoleService iRoleService; + private final IUserRoleRefService iUserRoleRefService; + + private final PasswordEncoder passwordEncoder; @Override @Transactional(rollbackFor = Exception.class) @@ -115,26 +121,29 @@ public class UserServiceImpl extends CrudServiceImpl updateWrapper = new UpdateWrapper<>(); - updateWrapper.set("mobile", null); - updateWrapper.eq("mobile", model.getMobile()); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getMobile, null); + updateWrapper.eq(SysUser::getMobile, model.getMobile()); + this.update(updateWrapper); + } + + // 如果邮箱有变化 则强制覆盖邮箱 + if(StringUtils.isNotEmpty(model.getEmail())){ + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getEmail, null); + updateWrapper.eq(SysUser::getEmail, model.getEmail()); this.update(updateWrapper); } @@ -150,11 +159,9 @@ public class UserServiceImpl extends CrudServiceImpl roleQueryWrapper = new QueryWrapper<>(); - roleQueryWrapper.eq("role_code", defRole); - roleQueryWrapper.eq( - FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC), - DictType.NO_YES_NO.getValue()); + LambdaUpdateWrapper roleQueryWrapper = new LambdaUpdateWrapper<>(); + roleQueryWrapper.eq(SysRole::getRoleCode, defRole); + roleQueryWrapper.eq(SysRole::getDeleted,DictType.NO_YES_NO.getValue()); SysRole sysRole = iRoleService.getOne(roleQueryWrapper); if(sysRole != null){ UserRoleRefModel userRoleRefModel = UserRoleRefModel.builder() @@ -207,7 +214,6 @@ public class UserServiceImpl extends CrudServiceImpl updateWrapper = new UpdateWrapper<>(); - updateWrapper.set("mobile", null); - updateWrapper.eq("mobile", model.getMobile()); - updateWrapper.notIn(MyBatisConstants.FIELD_ID, update.getId()); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getMobile, null); + updateWrapper.eq(SysUser::getMobile, model.getMobile()); + updateWrapper.notIn(SysUser::getId, update.getId()); + this.update(updateWrapper); + } + + // 如果邮箱有变化 则强制覆盖邮箱 + if(StringUtils.isNotEmpty(model.getEmail())){ + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getEmail, null); + updateWrapper.eq(SysUser::getEmail, model.getEmail()); + updateWrapper.notIn(SysUser::getId, update.getId()); this.update(updateWrapper); } @@ -255,11 +270,9 @@ public class UserServiceImpl extends CrudServiceImpl updateWrapper = new UpdateWrapper<>(); - updateWrapper.set("enable", enable) - .eq( - FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID), userId - ); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getEnable, enable); + updateWrapper.eq(SysUser::getId, userId); if(this.update(updateWrapper)){ // 刷新用户缓存 this.clearCache(Collections.singletonList(model)); @@ -418,13 +431,36 @@ public class UserServiceImpl extends CrudServiceImpl queryBuilder = new GenQueryBuilder<>(); - QueryWrapper queryWrapper = queryBuilder.build(); - queryWrapper.eq(key, username); - queryWrapper.eq( - FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC) - , "0"); + if(StrUtil.isBlank(username)){ + return null; + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getUsername, username); + queryWrapper.eq(SysUser::getDeleted, DictType.NO_YES_NO.getValue()); + SysUser user = this.getOne(queryWrapper); + return super.transformT2M(user); + } + + @Override + public UserModel queryByMobile(String mobile) { + if(StrUtil.isBlank(mobile)){ + return null; + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getMobile, mobile); + queryWrapper.eq(SysUser::getDeleted, DictType.NO_YES_NO.getValue()); + SysUser user = this.getOne(queryWrapper); + return super.transformT2M(user); + } + + @Override + public UserModel queryByEmail(String email) { + if(StrUtil.isBlank(email)){ + return null; + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getEmail, email); + queryWrapper.eq(SysUser::getDeleted, DictType.NO_YES_NO.getValue()); SysUser user = this.getOne(queryWrapper); return super.transformT2M(user); } @@ -446,7 +482,7 @@ public class UserServiceImpl extends CrudServiceImpl updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getEmail, updateUserEmailModel.getEmail()); + updateWrapper.eq(SysUser::getId, userModel.getId()); + boolean ret = this.update(updateWrapper); + if(ret){ + // 刷新用户缓存 + this.clearCache(Collections.singletonList(userModel)); + } + + return false; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateUserMobile(UpdateUserMobileModel updateUserMobileModel) { + UserModel userModel = UserUtil.getUserBySource(); + + String sourceMobile = userModel.getMobile(); + if(StrUtil.isNotEmpty(sourceMobile)){ + if(sourceMobile.equals(updateUserMobileModel.getMobile())){ + // 相同手机 + throw new ServiceException(SystemMsg.EXCEPTION_USER_MOBILE_EQ); + } + } + + + // 验证授权是否正确 + VerificationCodeUtil.checkCertificate( + VerificationTypeEnum.AUTH.getType(), updateUserMobileModel.getCertificate()); + + // 验证验证码是否正确 + VerificationCodeUtil.checkMobileCode( + updateUserMobileModel.getMobile(), updateUserMobileModel.getVerificationCode(), + VerificationTypeEnum.AUTH.getType()); + + // 验证手机号是否已经存在 + boolean verification = + uniqueVerificationByMobile(userModel.getId(), updateUserMobileModel.getMobile()); + if(!verification){ + // 重复 + throw new ServiceException(SystemMsg.EXCEPTION_USER_MOBILE_UNIQUE); + } + + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysUser::getMobile, updateUserMobileModel.getMobile()); + updateWrapper.eq(SysUser::getId, userModel.getId()); + boolean ret = this.update(updateWrapper); + if(ret){ + // 刷新用户缓存 + this.clearCache(Collections.singletonList(userModel)); + } + + return false; + } + @Override @Transactional(rollbackFor = Exception.class) public boolean resetPassword(UserPassword userPassword) { @@ -558,21 +669,15 @@ public class UserServiceImpl extends CrudServiceImpl wrapper = new QueryWrapper<>(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); // name 唯一 - wrapper.eq("username", model.getUsername()); + wrapper.eq(SysUser::getUsername, model.getUsername()); // 重复校验排除自身 if(StringUtils.isNotEmpty(model.getId())){ - wrapper.notIn(MyBatisConstants.FIELD_ID, model.getId()); + wrapper.notIn(SysUser::getId, model.getId()); + } + return super.count(wrapper) == 0; + } + + /** + * 唯一验证 邮箱 + * @param userId 用户ID + * @param email 邮箱 + * @return Integer + */ + @Transactional(readOnly = true) + public boolean uniqueVerificationByEmail(String userId, String email){ + if(StrUtil.isEmpty(email)){ + return false; } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + // name 唯一 + wrapper.eq(SysUser::getEmail, email); + + // 重复校验排除自身 + if(StringUtils.isNotEmpty(userId)){ + wrapper.notIn(SysUser::getId, userId); + } + return super.count(wrapper) == 0; + } + + /** + * 唯一验证 手机 + * @param userId 用户ID + * @param mobile 手机 + * @return Integer + */ + @Transactional(readOnly = true) + public boolean uniqueVerificationByMobile(String userId, String mobile){ + if(StrUtil.isEmpty(mobile)){ + return false; + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + // name 唯一 + wrapper.eq(SysUser::getMobile, mobile); + + // 重复校验排除自身 + if(StringUtils.isNotEmpty(userId)){ + wrapper.notIn(SysUser::getId, userId); + } return super.count(wrapper) == 0; } 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 5e051bb..12d06ed 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 @@ -15,34 +15,23 @@ */ package org.opsli.modulars.system.user.web; -import cn.hutool.core.collection.CollUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.user.UserOrgRefApi; -import org.opsli.api.wrapper.system.org.SysOrgModel; 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.api.wrapper.system.user.UserWebModel; import org.opsli.common.annotation.ApiRestController; import org.opsli.common.exception.ServiceException; import org.opsli.core.autoconfigure.properties.GlobalProperties; import org.opsli.core.msg.CoreMsg; -import org.opsli.core.persistence.Page; -import org.opsli.core.persistence.querybuilder.GenQueryBuilder; -import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.utils.UserUtil; import org.opsli.modulars.system.SystemMsg; -import org.opsli.modulars.system.user.entity.SysUserOrgRef; -import org.opsli.modulars.system.user.entity.SysUserWeb; import org.opsli.modulars.system.user.service.IUserOrgRefService; -import org.opsli.modulars.system.user.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import java.util.List; @@ -65,19 +54,19 @@ public class UserOrgRefRestController implements UserOrgRefApi { private IUserOrgRefService iUserOrgRefService; @Override - public ResultVo> findListByUserId(String userId) { + public ResultWrapper> findListByUserId(String userId) { List listByUserId = iUserOrgRefService.findListByUserId(userId); - return ResultVo.success(listByUserId); + return ResultWrapper.getSuccessResultWrapper(listByUserId); } /** * 设置组织 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @Override - @RequiresPermissions("system_user_setOrg") - public ResultVo setOrg(UserOrgRefWebModel model) { + @PreAuthorize("hasAuthority('system_user_setOrg')") + public ResultWrapper setOrg(UserOrgRefWebModel model) { // 演示模式 不允许操作 this.demoError(); @@ -86,18 +75,18 @@ public class UserOrgRefRestController implements UserOrgRefApi { // 权限设置失败 throw new ServiceException(SystemMsg.EXCEPTION_USER_ORG_ERROR); } - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } /** * 根据 userId 获得用户默认组织 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo getDefOrgByUserId(String userId) { + public ResultWrapper getDefOrgByUserId(String userId) { UserOrgRefModel userOrgRefModel = iUserOrgRefService.getDefOrgByUserId(userId); - return ResultVo.success(userOrgRefModel); + return ResultWrapper.getSuccessResultWrapper(userOrgRefModel); } 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 f5157c5..ee2b9aa 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,17 +17,16 @@ 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.DesensitizedUtil; import cn.hutool.core.util.StrUtil; -import com.alibaba.excel.util.CollectionUtils; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.encrypt.EncryptModel; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.system.user.UserApi; import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.options.OptionsModel; @@ -35,44 +34,36 @@ import org.opsli.api.wrapper.system.role.RoleModel; import org.opsli.api.wrapper.system.tenant.TenantModel; import org.opsli.api.wrapper.system.user.*; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.enums.DictType; +import org.opsli.common.enums.VerificationTypeEnum; import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.TokenException; import org.opsli.common.utils.FieldUtil; import org.opsli.common.utils.WrapperUtil; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.msg.TokenMsg; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.core.persistence.querybuilder.conf.WebQueryConf; -import org.opsli.core.utils.OptionsUtil; -import org.opsli.core.utils.OrgUtil; -import org.opsli.core.utils.TenantUtil; -import org.opsli.core.utils.UserUtil; +import org.opsli.core.utils.*; import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.user.entity.SysUser; import org.opsli.modulars.system.user.entity.SysUserWeb; import org.opsli.modulars.system.user.service.IUserRoleRefService; import org.opsli.modulars.system.user.service.IUserService; -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.bind.annotation.RequestBody; -import org.springframework.web.multipart.MultipartFile; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Iterator; import java.util.List; +import java.util.Optional; /** @@ -92,22 +83,22 @@ public class UserRestController extends BaseRestController getInfo(HttpServletRequest request) { + public ResultWrapper getInfo(HttpServletRequest request) { UserModel currUser = UserUtil.getUserBySource(); return this.getInfoById(currUser.getId()); } /** * 当前登陆用户信息 By Id - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "当前登陆用户信息 By Id", notes = "当前登陆用户信息 By Id") @Override - public ResultVo getInfoById(String userId) { + public ResultWrapper getInfoById(String userId) { UserModel currUser = UserUtil.getUserBySource(userId); if(currUser == null){ throw new TokenException(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY); @@ -143,17 +134,21 @@ public class UserRestController extends BaseRestController getOrg() { + public ResultWrapper getOrg() { UserModel user = UserUtil.getUser(); return this.getOrgByUserId(user.getId()); } @@ -161,53 +156,136 @@ public class UserRestController extends BaseRestController getOrgByUserId(String userId) { + public ResultWrapper getOrgByUserId(String userId) { List orgListByUserId = UserUtil.getOrgListByUserId(userId); - return ResultVo.success(orgListByUserId); + return ResultWrapper.getSuccessResultWrapper(orgListByUserId); } /** * 根据 userId 获得用户角色Id集合 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "根据 userId 获得用户角色Id集合", notes = "根据 userId 获得用户角色Id集合") @Override - public ResultVo> getRoleIdsByUserId(String userId) { + public ResultWrapper> getRoleIdsByUserId(String userId) { List roleIdList = iUserRoleRefService.getRoleIdList(userId); - return ResultVo.success(roleIdList); + return ResultWrapper.getSuccessResultWrapper(roleIdList); } /** * 修改密码 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改密码", notes = "修改密码") @Override - public ResultVo updatePassword(UserPassword userPassword) { + public ResultWrapper updatePassword(EncryptModel encryptModel) { // 演示模式 不允许操作 super.demoError(); + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + UserPassword userPassword = WrapperUtil.transformInstance( + asymmetricDecryptToObj, UserPassword.class); + + // 验证对象 + ValidatorUtil.verify(userPassword); + UserModel user = UserUtil.getUserBySource(); userPassword.setUserId(user.getId()); IService.updatePasswordByCheckOld(userPassword); - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); + } + + /** + * 修改密码 忘记密码 + * @return ResultWrapper + */ + @Override + public ResultWrapper updatePasswordByForget(EncryptModel encryptModel) { + // 演示模式 不允许操作 + super.demoError(); + + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + UpdateUserPasswordByForgetModel updateUserPasswordByForgetModel = WrapperUtil.transformInstance( + asymmetricDecryptToObj, UpdateUserPasswordByForgetModel.class); + + // 验证授权是否正确 + VerificationCodeUtil.checkCertificate( + VerificationTypeEnum.AUTH.getType(), updateUserPasswordByForgetModel.getCertificate()); + + UserModel userBySource = UserUtil.getUserBySource(); + + // 转换模型 + ToUserPassword userPassword = new ToUserPassword(); + userPassword.setUserId(userBySource.getId()); + userPassword.setNewPassword(updateUserPasswordByForgetModel.getNewPassword()); + + IService.updatePasswordByNotCheckOld(userPassword); + return ResultWrapper.getSuccessResultWrapper(); + } + + /** + * 修改邮箱 + * @return ResultWrapper + */ + @ApiOperation(value = "修改邮箱", notes = "修改邮箱") + @Override + public ResultWrapper updateEmail(EncryptModel encryptModel) { + // 演示模式 不允许操作 + super.demoError(); + + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + UpdateUserEmailModel updateUserEmailModel = WrapperUtil.transformInstance( + asymmetricDecryptToObj, UpdateUserEmailModel.class); + + // 验证对象 + ValidatorUtil.verify(updateUserEmailModel); + + // 修改用户邮箱 + IService.updateUserEmail(updateUserEmailModel); + return ResultWrapper.getSuccessResultWrapper(); + } + + /** + * 修改手机 + * @return ResultWrapper + */ + @ApiOperation(value = "修改手机", notes = "修改手机") + @Override + public ResultWrapper updateMobile(EncryptModel encryptModel) { + // 演示模式 不允许操作 + super.demoError(); + + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + UpdateUserMobileModel updateUserMobileModel = WrapperUtil.transformInstance( + asymmetricDecryptToObj, UpdateUserMobileModel.class); + + // 验证对象 + ValidatorUtil.verify(updateUserMobileModel); + + // 修改用户邮箱 + IService.updateUserMobile(updateUserMobileModel); + return ResultWrapper.getSuccessResultWrapper(); } /** * 上传头像 * @param userAvatarModel 图片地址 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "上传头像", notes = "上传头像") @Override - public ResultVo updateAvatar(UserAvatarModel userAvatarModel) { + public ResultWrapper updateAvatar(UserAvatarModel userAvatarModel) { UserModel user = UserUtil.getUserBySource(); // 更新头像至数据库 UserModel userModel = new UserModel(); @@ -216,40 +294,56 @@ public class UserRestController extends BaseRestController updatePasswordById(ToUserPassword userPassword) { + public ResultWrapper updatePasswordById(EncryptModel encryptModel) { // 演示模式 不允许操作 super.demoError(); + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + ToUserPassword userPassword = WrapperUtil.transformInstance( + asymmetricDecryptToObj, ToUserPassword.class); + + // 验证对象 + ValidatorUtil.verify(userPassword); + IService.updatePasswordByNotCheckOld(userPassword); - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } /** * 重置密码 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "重置密码", notes = "重置密码") - @RequiresPermissions("system_user_resetPassword") - @EnableLog + @PreAuthorize("hasAuthority('system_user_resetPassword')") + @OperateLogger(description = "重置密码", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo resetPasswordById(String userId) { + public ResultWrapper resetPasswordById(EncryptModel encryptModel) { // 演示模式 不允许操作 super.demoError(); + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + String userId = JSONUtil.parseObj(asymmetricDecryptToObj).getStr("userId"); + if(StrUtil.isBlank(userId)){ + throw new ServiceException(SystemMsg.EXCEPTION_USER_ILLEGAL_PARAMETER); + } + // 配置文件默认密码 String defPass = globalProperties.getAuth().getDefaultPass(); @@ -265,45 +359,57 @@ public class UserRestController extends BaseRestController enableAccount(String userId, String enable) { + public ResultWrapper enableAccount(EncryptModel encryptModel) { // 演示模式 不允许操作 super.demoError(); + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + EnableUserModel enableUserModel = WrapperUtil.transformInstance( + asymmetricDecryptToObj, EnableUserModel.class); + + // 验证对象 + ValidatorUtil.verify(enableUserModel); + // 变更账户状态 - boolean lockAccountFlag = IService.enableAccount(userId, enable); + boolean lockAccountFlag = IService.enableAccount( + enableUserModel.getUserId(), enableUserModel.getEnabled()); if(!lockAccountFlag){ - return ResultVo.error("变更用户状态失败"); + // 变更状态失败 + return ResultWrapper.getCustomResultWrapper(SystemMsg.EXCEPTION_CHANGE_STATUS); } - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } /** * 用户信息 查一条 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "获得单条用户信息", notes = "获得单条用户信息 - ID") // 因为工具类 使用到该方法 不做权限验证 - //@RequiresPermissions("system_user_select") + //@PreAuthorize("hasAuthority('system_user_select')") @Override - public ResultVo get(UserModel model) { + public ResultWrapper get(UserModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -312,12 +418,12 @@ public class UserRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, + public ResultWrapper findPage(Integer pageNo, Integer pageSize, String orgIdGroup, HttpServletRequest request) { QueryBuilder queryBuilder = new WebQueryBuilder<>( @@ -335,11 +441,10 @@ public class UserRestController extends BaseRestController findPageByTenant(Integer pageNo, Integer pageSize, + public ResultWrapper findPageByTenant(Integer pageNo, Integer pageSize, HttpServletRequest request) { // 转换字段 WebQueryConf conf = new WebQueryConf(); @@ -368,153 +473,177 @@ public class UserRestController extends BaseRestController insert(UserModel model) { + public ResultWrapper insert(UserModel model) { // 调用新增方法 UserModel userModel = IService.insert(model); - return ResultVo.success("新增用户信息成功", userModel); + return ResultWrapper.getSuccessResultWrapperByMsg("新增用户信息成功") + .setData(userModel); } /** * 用户信息 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改用户信息", notes = "修改用户信息") - @RequiresPermissions("system_user_update") - @EnableLog + @PreAuthorize("hasAuthority('system_user_update')") + @OperateLogger(description = "修改用户信息", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(UserModel model) { + public ResultWrapper update(UserModel model) { // 演示模式 不允许操作 super.demoError(); // 调用修改方法 IService.update(model); - return ResultVo.success("修改用户信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改用户信息成功"); } /** * 用户信息 自身修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改自身用户信息", notes = "修改自身用户信息") - @EnableLog + @OperateLogger(description = "修改自身用户信息", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo updateSelf(UserModel model) { + public ResultWrapper updateSelf(UserModel model) { UserModel currUser = UserUtil.getUserBySource(); if(!StringUtils.equals(currUser.getId(), model.getId())){ // 非法参数 防止其他用户 通过该接口 修改非自身用户数据 throw new ServiceException(SystemMsg.EXCEPTION_USER_ILLEGAL_PARAMETER); } + + // 防止篡改手机号、邮箱号 + model.setMobile(null); + model.setEmail(null); + // 调用修改方法 IService.update(model); - return ResultVo.success("修改用户信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改用户信息成功"); } /** * 用户信息 删除 - * @param id ID - * @return ResultVo + * @param encryptModel 加密 id ID + * @return ResultWrapper */ @ApiOperation(value = "删除用户信息数据", notes = "删除用户信息数据") - @RequiresPermissions("system_user_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_user_delete')") + @OperateLogger(description = "删除用户信息数据", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(EncryptModel encryptModel) { // 演示模式 不允许操作 super.demoError(); + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + String id = JSONUtil.parseObj(asymmetricDecryptToObj).getStr("id"); + IService.delete(id); - return ResultVo.success("删除用户信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除用户信息成功"); } /** * 用户信息 批量删除 - * @param ids ID 数组 - * @return ResultVo + * @param encryptModel 加密 ID 数组 + * @return ResultWrapper */ @ApiOperation(value = "批量删除用户信息数据", notes = "批量删除用户信息数据") - @RequiresPermissions("system_user_delete") - @EnableLog + @PreAuthorize("hasAuthority('system_user_delete')") + @OperateLogger(description = "批量删除用户信息数据", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(EncryptModel encryptModel) { // 演示模式 不允许操作 super.demoError(); + Object asymmetricDecryptToObj = CryptoUtil.asymmetricDecryptToObj(encryptModel.getEncryptData()); + // 转换模型 + String ids = JSONUtil.parseObj(asymmetricDecryptToObj).getStr("ids"); + String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除用户信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除用户信息成功"); } /** - * 用户信息 Excel 导出 + * 用户信息 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('system_user_export', 'system_user_import')") + @Override + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, UserApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } + + + /** + * 用户信息 Excel 导出 * @param response response */ @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("system_user_export") - @EnableLog + @PreAuthorize("hasAuthority('system_user_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.SELECT, db = true) @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(UserApi.SUB_TITLE, queryBuilder.build(), response, method); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } /** * 用户信息 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("system_user_import") - @EnableLog + @PreAuthorize("hasAuthority('system_user_import')") + @OperateLogger(description = "用户信息 Excel 导入", + module = ModuleEnum.MODULE_USER, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { return super.importExcel(request); } - /** - * 用户信息 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("system_user_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(UserApi.SUB_TITLE, response, method); - } /** * 根据 username 获得用户 * @param username 用户名 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "根据 username 获得用户", notes = "根据 username 获得用户") @Override - public ResultVo getUserByUsername(String username) { + public ResultWrapper getUserByUsername(String username) { UserModel userModel = IService.queryByUserName(username); if(userModel == null){ // 暂无该用户 @@ -522,18 +651,43 @@ public class UserRestController extends BaseRestController getUserByMobile(String mobile) { + UserModel userModel = IService.queryByMobile(mobile); + if(userModel == null){ + // 暂无该用户 + throw new ServiceException(SystemMsg.EXCEPTION_USER_NULL.getCode(), + StrUtil.format(SystemMsg.EXCEPTION_USER_NULL.getMessage(), mobile) + ); + } + return ResultWrapper.getSuccessResultWrapper(userModel); } + @ApiOperation(value = "根据 邮箱 获得用户", notes = "根据 邮箱 获得用户") + @Override + public ResultWrapper getUserByEmail(String email) { + UserModel userModel = IService.queryByEmail(email); + if(userModel == null){ + // 暂无该用户 + throw new ServiceException(SystemMsg.EXCEPTION_USER_NULL.getCode(), + StrUtil.format(SystemMsg.EXCEPTION_USER_NULL.getMessage(), email) + ); + } + return ResultWrapper.getSuccessResultWrapper(userModel); + } /** * 切换租户 * @param tenantId 租户ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "切换租户", notes = "切换租户") @Override - public ResultVo switchTenant(String tenantId) { + public ResultWrapper switchTenant(String tenantId) { UserModel currUser = UserUtil.getUserBySource(); if (!DictType.NO_YES_YES.getValue().equals(currUser.getEnableSwitchTenant())){ // 不允许切换租户 @@ -585,18 +739,18 @@ public class UserRestController extends BaseRestController switchOneself() { + public ResultWrapper switchOneself() { UserModel currUser = UserUtil.getUserBySource(); if (!DictType.NO_YES_YES.getValue().equals(currUser.getEnableSwitchTenant())){ // 不允许切换租户 @@ -607,8 +761,8 @@ public class UserRestController extends BaseRestController getRoles(String userId) { + public ResultWrapper getRoles(String userId) { List roleIdList = iUserRoleRefService.getRoleIdList(userId); String defRoleId = iUserRoleRefService.getDefRoleId(userId); @@ -79,73 +76,71 @@ public class UserRoleRefRestController implements UserRoleRefApi { .defRoleId(defRoleId) .build(); - return ResultVo.success(userRoleRefModel); + return ResultWrapper.getSuccessResultWrapper(userRoleRefModel); } /** * 设置角色 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @Override - @RequiresPermissions("system_user_setRole") - public ResultVo setRoles(UserRoleRefModel model) { + @PreAuthorize("hasAuthority('system_user_setRole')") + public ResultWrapper setRoles(UserRoleRefModel model) { // 演示模式 不允许操作 this.demoError(); boolean ret = iUserRoleRefService.setRoles(model); if(ret){ - return ResultVo.success(); + return ResultWrapper.getSuccessResultWrapper(); } // 权限设置失败 - return ResultVo.error(SystemMsg.EXCEPTION_USER_ROLES_ERROR.getCode(), - SystemMsg.EXCEPTION_USER_ROLES_ERROR.getMessage() - ); + return ResultWrapper.getCustomResultWrapper(SystemMsg.EXCEPTION_USER_ROLES_ERROR); } /** * 根据 userId 获得用户角色 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo> getRolesByUserId(String userId) { + public ResultWrapper> getRolesByUserId(String userId) { List roleCodeList = iUserRoleRefService.getRoleCodeList(userId); - return ResultVo.success(roleCodeList); + return ResultWrapper.getSuccessResultWrapper(roleCodeList); } /** * 根据 userId 获得用户默认角色 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo getDefRoleByUserId(String userId) { + public ResultWrapper getDefRoleByUserId(String userId) { RoleModel defRoleByUserId = iUserRoleRefService.getDefRoleByUserId(userId); - return ResultVo.success(defRoleByUserId); + return ResultWrapper.getSuccessResultWrapper(defRoleByUserId); } /** * 根据 userId 获得用户权限 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo> getAllPerms(String userId) { + public ResultWrapper> getAllPerms(String userId) { List allPerms = iUserRoleRefService.getAllPerms(userId); - return ResultVo.success(allPerms); + return ResultWrapper.getSuccessResultWrapper(allPerms); } /** * 根据 userId 获得用户菜单 * @param userId 用户Id - * @return ResultVo + * @return ResultWrapper */ @Override - public ResultVo> getMenuListByUserId(String userId) { + public ResultWrapper> getMenuListByUserId(String userId) { List menuModelList = iUserRoleRefService.getMenuListByUserId(userId); - return ResultVo.success(menuModelList); + return ResultWrapper.getSuccessResultWrapper(menuModelList); } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/api/ApiController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/api/ApiController.java index 41ccd1b..89139d9 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/api/ApiController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/api/ApiController.java @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping; /** * API 版本控制测试 * - * @author 周鹏程 + * @author Parker * @date 2021年10月27日12:50:00 */ @Api(tags = "API-测试版本控制") @@ -44,4 +44,4 @@ public class ApiController { return "fun 5"; } -} \ No newline at end of file +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/CommonRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/CommonRestController.java new file mode 100644 index 0000000..44c777d --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/CommonRestController.java @@ -0,0 +1,152 @@ +/** + * 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.modulars.tools.common; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.base.encrypt.EncryptModel; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.web.system.role.RoleMenuRefApi; +import org.opsli.api.wrapper.system.options.OptionsModel; +import org.opsli.common.annotation.ApiRestController; +import org.opsli.common.annotation.Limiter; +import org.opsli.common.enums.OptionsType; +import org.opsli.common.enums.VerificationTypeEnum; +import org.opsli.common.exception.ServiceException; +import org.opsli.common.utils.WrapperUtil; +import org.opsli.core.msg.TokenMsg; +import org.opsli.core.utils.CryptoUtil; +import org.opsli.core.utils.OptionsUtil; +import org.opsli.core.utils.ValidatorUtil; +import org.opsli.modulars.system.login.dto.EmailCodeModel; +import org.opsli.modulars.system.login.dto.MobileCodeModel; +import org.opsli.modulars.tools.common.bean.VerificationCodeBean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + + +/** + * 公共 Controller + * + * @author Parker + * @date 2020-09-16 17:33 + */ +@Api(tags = RoleMenuRefApi.TITLE) +@Slf4j +@AllArgsConstructor +@ApiRestController("/{ver}/common") +public class CommonRestController { + + private final VerificationCodeBean verificationCodeBean; + + /** + * 获得公钥 + */ + @Limiter + @ApiOperation(value = "获得公钥", notes = "获得公钥") + @GetMapping("/public-key") + public ResultWrapper getPublicKey(){ + // 获得公钥 + OptionsModel option = OptionsUtil.getOptionByCode(OptionsType.CRYPTO_ASYMMETRIC_PUBLIC_KEY); + if(option != null){ + return ResultWrapper.getSuccessResultWrapper(option.getOptionValue()); + } + + // 失败 + return ResultWrapper.getErrorResultWrapper(); + } + + + + /** + * 生成Email 验证码 + * + * @param encryptModel 加密参数 + */ + @Limiter(qps = 1) + @ApiOperation(value = "生成Email 验证码", notes = "生成Email 验证码") + @PostMapping("/email/create-code") + public ResultWrapper createEmailCode(@RequestBody EncryptModel encryptModel) { + // 解密对象 + Object dataToObj = CryptoUtil + .asymmetricDecryptToObj(encryptModel.getEncryptData()); + + // 转换模型 + EmailCodeModel emailCodeModel = WrapperUtil.transformInstance(dataToObj, EmailCodeModel.class); + + // 验证对象 + ValidatorUtil.verify(emailCodeModel); + + // 验证type + VerificationTypeEnum.getEnumByType(emailCodeModel.getType()) + .orElseThrow(() -> new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL)); + + // 发送短信 + try { + verificationCodeBean.sendEmailCode(emailCodeModel.getEmail(), emailCodeModel.getType()); + }catch (ServiceException e){ + return ResultWrapper.getCustomResultWrapper( + e.getCode(), e.getErrorMessage()); + }catch (Exception e){ + log.error(e.getMessage(), e); + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapperByMsg("发送邮件成功"); + } + + + + /** + * 生成Mobile 验证码 + * + * @param encryptModel 加密参数 + */ + @Limiter(qps = 1) + @ApiOperation(value = "生成Mobile 验证码", notes = "生成Mobile 验证码") + @PostMapping("/mobile/create-code") + public ResultWrapper createMobileCode(@RequestBody EncryptModel encryptModel) { + // 解密对象 + Object dataToObj = CryptoUtil + .asymmetricDecryptToObj(encryptModel.getEncryptData()); + + // 转换模型 + MobileCodeModel mobileCodeModel = WrapperUtil.transformInstance(dataToObj, MobileCodeModel.class); + + // 验证对象 + ValidatorUtil.verify(mobileCodeModel); + + // 验证type + VerificationTypeEnum.getEnumByType(mobileCodeModel.getType()) + .orElseThrow(() -> new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL)); + + // 发送短信 + try { + verificationCodeBean.sendMobileCode(mobileCodeModel.getMobile(), mobileCodeModel.getType()); + }catch (ServiceException e){ + return ResultWrapper.getCustomResultWrapper( + e.getCode(), e.getErrorMessage()); + }catch (Exception e){ + log.error(e.getMessage(), e); + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapperByMsg("发送短信成功"); + } + + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/OperationAuthRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/OperationAuthRestController.java new file mode 100644 index 0000000..3f82d70 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/OperationAuthRestController.java @@ -0,0 +1,171 @@ +/** + * 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.modulars.tools.common; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.web.system.role.RoleMenuRefApi; +import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.common.annotation.ApiRestController; +import org.opsli.common.annotation.Limiter; +import org.opsli.common.enums.VerificationTypeEnum; +import org.opsli.common.exception.ServiceException; +import org.opsli.core.msg.TokenMsg; +import org.opsli.core.utils.UserUtil; +import org.opsli.core.utils.VerificationCodeUtil; +import org.opsli.modulars.tools.common.bean.VerificationCodeBean; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + + +/** + * 操作身份认证 Controller + * + * @author Parker + * @date 2020-09-16 17:33 + */ +@Api(tags = RoleMenuRefApi.TITLE) +@Slf4j +@AllArgsConstructor +@ApiRestController("/{ver}/operation/auth") +public class OperationAuthRestController { + + + private final VerificationCodeBean verificationCodeBean; + + + /** + * 生成Email 验证码 + * 直接获取当前用户 + */ + @Limiter(qps = 1) + @ApiOperation(value = "生成Email 验证码(自身)", notes = "生成Email 验证码(自身)") + @PostMapping("/email/create-code/{type}") + public ResultWrapper createEmailCode(@PathVariable String type) { + UserModel user = UserUtil.getUser(); + + // 验证type + VerificationTypeEnum.getEnumByType(type) + .orElseThrow(() -> new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL)); + + // 发送邮件 + try { + verificationCodeBean.sendEmailCode(user.getEmail(), type); + }catch (ServiceException e){ + return ResultWrapper.getCustomResultWrapper( + e.getCode(), e.getErrorMessage()); + }catch (Exception e){ + log.error(e.getMessage(), e); + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapperByMsg("发送邮件成功"); + } + + /** + * 验证 Email 验证码 + * 直接获取当前用户 + * + * @return ResultWrapper 授权码 + */ + @Limiter(qps = 1) + @ApiOperation(value = "验证Email 验证码(自身)", notes = "验证Email 验证码(自身)") + @PostMapping("/email/check-code/{type}/{code}") + public ResultWrapper checkEmailCode(@PathVariable String type, @PathVariable String code) { + UserModel user = UserUtil.getUserBySource(); + + // 验证type + VerificationTypeEnum.getEnumByType(type) + .orElseThrow(() -> new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL)); + + String certificate; + + // 验证 邮箱验证码,同时生成一个验证后的唯一凭证 + try { + certificate = VerificationCodeUtil.checkEmailCodeToCreateCertificate(user.getEmail(), code, type); + }catch (ServiceException e){ + return ResultWrapper.getCustomResultWrapper( + e.getCode(), e.getErrorMessage()); + }catch (Exception e){ + log.error(e.getMessage(), e); + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificate); + } + + + /** + * 生成Mobile 验证码 + * 直接获取当前用户 + */ + @Limiter(qps = 1) + @ApiOperation(value = "生成Mobile 验证码(自身)", notes = "生成Mobile 验证码(自身)") + @PostMapping("/mobile/create-code/{type}") + public ResultWrapper createMobileCode(@PathVariable String type) { + UserModel user = UserUtil.getUser(); + + // 验证type + VerificationTypeEnum.getEnumByType(type) + .orElseThrow(() -> new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL)); + + try { + verificationCodeBean.sendMobileCode(user.getMobile(), type); + }catch (ServiceException e){ + return ResultWrapper.getCustomResultWrapper( + e.getCode(), e.getErrorMessage()); + }catch (Exception e){ + log.error(e.getMessage(), e); + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapperByMsg("发送短信成功"); + } + + /** + * 验证 Mobile 验证码 + * 直接获取当前用户 + * + * @return ResultWrapper 授权码 + */ + @Limiter(qps = 1) + @ApiOperation(value = "验证 Mobile 验证码(自身)", notes = "验证 Mobile 验证码(自身)") + @PostMapping("/mobile/check-code/{type}/{code}") + public ResultWrapper checkMobileCode(@PathVariable String type, @PathVariable String code) { + UserModel user = UserUtil.getUserBySource(); + + // 验证type + VerificationTypeEnum.getEnumByType(type) + .orElseThrow(() -> new ServiceException(TokenMsg.EXCEPTION_CAPTCHA_ARGS_NULL)); + + String certificate; + // 验证 手机验证码,同时生成一个验证后的唯一凭证 + try { + certificate = + VerificationCodeUtil + .checkMobileCodeToCreateCertificate(user.getMobile(), code, type); + }catch (ServiceException e){ + return ResultWrapper.getCustomResultWrapper( + e.getCode(), e.getErrorMessage()); + }catch (Exception e){ + log.error(e.getMessage(), e); + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificate); + } + + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/bean/VerificationCodeBean.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/bean/VerificationCodeBean.java new file mode 100644 index 0000000..f064ce9 --- /dev/null +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/common/bean/VerificationCodeBean.java @@ -0,0 +1,95 @@ +/** + * 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.modulars.tools.common.bean; + +import cn.hutool.core.map.MapUtil; +import com.jfinal.kit.Kv; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.core.autoconfigure.properties.GlobalProperties; +import org.opsli.core.options.EmailConfigFactory; +import org.opsli.core.utils.EnjoyUtil; +import org.opsli.core.utils.VerificationCodeUtil; +import org.opsli.plugins.email.EmailPlugin; +import org.opsli.plugins.sms.SmsFactory; +import org.opsli.plugins.sms.enums.SmsType; +import org.opsli.plugins.sms.model.SmsModel; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.Map; + +/** + * 验证码Bean + * + * @author 周鹏程 + * @date 2022-08-02 1:00 PM + **/ +@Slf4j +@AllArgsConstructor +@Component +public class VerificationCodeBean { + private static final String EMAIL_FTL = "/email/email_code.ftl"; + /** TODO 短信签名 请修改 */ + private static final String SMS_SIGN_NAME = "阿里云短信测试"; + /** TODO 短信模版编号 请修改 */ + private static final String SMS_TEMPLATE_CODE = "SMS_154950909"; + + private final EmailPlugin emailPlugin; + private final GlobalProperties globalProperties; + + /** + * 发送邮件验证码 + * @param email 邮箱地址 + */ + public void sendEmailCode(String email, String type){ + // 发送邮件 + VerificationCodeUtil.VerificationCodeModel verificationCodeModel = + VerificationCodeUtil.createEmailCode(email, type); + String subject = globalProperties.getSystemName() + " - 验证邮件"; + Kv kv = Kv.create() + .set("systemName", globalProperties.getSystemName()) + .set("verificationCode", verificationCodeModel.getVerificationCode()) + .set("expiredDate", verificationCodeModel.getExpiredDate()) + .set("expiredMinute", verificationCodeModel.getExpiredMinute()); + String content = EnjoyUtil.render(EMAIL_FTL, kv); + + emailPlugin + .send(email, subject, content, true, + EmailConfigFactory.INSTANCE.getConfig()); + } + + /** + * 发送手机验证码 + * @param mobile 手机号 + */ + public void sendMobileCode(String mobile, String type){ + // 发送短信 + VerificationCodeUtil.VerificationCodeModel verificationCodeModel = + VerificationCodeUtil.createMobileCode(mobile, type); + + Map templateParam = MapUtil.newHashMap(1); + templateParam.put("code", verificationCodeModel.getVerificationCode()); + SmsModel smsModel = SmsModel.builder() + .signName(SMS_SIGN_NAME) + .templateCode(SMS_TEMPLATE_CODE) + .templateParam(templateParam) + .tels(Collections.singletonList(mobile)) + .build(); + SmsFactory.sendSms(SmsType.ALIYUN, smsModel); + } + +} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/email/web/EmailRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/email/web/EmailRestController.java index f0747ee..4b9db4b 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/email/web/EmailRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/email/web/EmailRestController.java @@ -3,7 +3,7 @@ package org.opsli.modulars.tools.email.web; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; import org.opsli.core.options.EmailConfigFactory; import org.opsli.plugins.email.EmailPlugin; @@ -30,18 +30,18 @@ public class EmailRestController { /** * 测试发送邮件 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "测试发送邮件", notes = "测试发送邮件") @PostMapping("/testSend") - public ResultVo testSend(@RequestBody EmailModel model) { + public ResultWrapper testSend(@RequestBody EmailModel model) { try { emailPlugin .send(model.getTo(), model.getSubject(), model.getContent(), EmailConfigFactory.INSTANCE.getConfig()); - return ResultVo.success("邮件发送成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("邮件发送成功"); }catch (Exception e){ - return ResultVo.error("邮件发送失败 - " + e.getMessage()); + return ResultWrapper.getErrorResultWrapper().setMsg("邮件发送失败 - " + e.getMessage()); } } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/oss/web/OssRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/oss/web/OssRestController.java index 5ad50c9..fa1c7f5 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/oss/web/OssRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/oss/web/OssRestController.java @@ -2,14 +2,11 @@ package org.opsli.modulars.tools.oss.web; import cn.hutool.core.io.FileUtil; import com.alibaba.excel.util.CollectionUtils; -import com.baomidou.mybatisplus.extension.service.IService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.opsli.api.base.result.ResultVo; -import org.opsli.api.wrapper.system.user.UserModel; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; -import org.opsli.core.utils.UserUtil; import org.opsli.modulars.system.SystemMsg; import org.opsli.plugins.oss.OssStorageFactory; import org.opsli.plugins.oss.service.BaseOssStorageService; @@ -38,18 +35,17 @@ public class OssRestController { /** * 文件上传 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "文件上传", notes = "文件上传") @PostMapping("/upload") - public ResultVo upload(MultipartHttpServletRequest request) { + public ResultWrapper upload(MultipartHttpServletRequest request) { Iterator itr = request.getFileNames(); String uploadedFile = itr.next(); List files = request.getFiles(uploadedFile); if (CollectionUtils.isEmpty(files)) { // 请选择文件 - return ResultVo.error(SystemMsg.EXCEPTION_USER_FILE_NULL.getCode(), - SystemMsg.EXCEPTION_USER_FILE_NULL.getMessage()); + return ResultWrapper.getCustomResultWrapper(SystemMsg.EXCEPTION_USER_FILE_NULL); } try { @@ -62,11 +58,11 @@ public class OssRestController { BaseOssStorageService.FileAttr fileAttr = ossStorageService.upload( multipartFile.getInputStream(), FileUtil.extName(filename)); - return ResultVo.success(fileAttr); + return ResultWrapper.getSuccessResultWrapper(fileAttr); }catch (IOException e){ log.error(e.getMessage(), e); } - return ResultVo.error(); + return ResultWrapper.getErrorResultWrapper(); } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/searchhis/web/SearchHisRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/searchhis/web/SearchHisRestController.java index 974f30a..ec24dd8 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/searchhis/web/SearchHisRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/tools/searchhis/web/SearchHisRestController.java @@ -18,7 +18,7 @@ package org.opsli.modulars.tools.searchhis.web; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; import org.opsli.common.annotation.Limiter; import org.opsli.common.annotation.SearchHis; @@ -45,11 +45,11 @@ public class SearchHisRestController { @Limiter @ApiOperation(value = "获得搜索历史记录", notes = "获得搜索历史记录") @PostMapping("/getSearchHis") - public ResultVo getSearchHis(String key, Integer count, HttpServletRequest request){ + public ResultWrapper getSearchHis(String key, Integer count, HttpServletRequest request){ Set searchHis = SearchHisUtil.getSearchHis(request, key, count); - return ResultVo.success(searchHis); + return ResultWrapper.getSuccessResultWrapper(searchHis); } /** diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/entity/TestCar.java b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/entity/TestCar.java old mode 100644 new mode 100755 index a9c537d..812ed4b --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/entity/TestCar.java +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/entity/TestCar.java @@ -15,6 +15,7 @@ */ package org.opsli.modulars.gentest.carinfo.entity; +import java.math.BigDecimal; import java.util.Date; import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.TableField; @@ -24,10 +25,10 @@ import lombok.EqualsAndHashCode; import org.opsli.core.base.entity.BaseEntity; /** - * 汽车信息 + * 测试汽车 Entity * * @author Parker - * @date 2020-12-20 20:12:57 + * @date 2022-08-06 23:53:30 */ @Data @EqualsAndHashCode(callSuper = false) @@ -52,14 +53,17 @@ public class TestCar extends BaseEntity { // ======================================== + + + + + /** 多租户字段 */ private String tenantId; - /** 组织机构 */ - private String orgIds; - /** 逻辑删除字段 */ @TableLogic - private String deleted; + private Integer deleted; + -} +} \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/TestCarMapper.java b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/TestCarMapper.java old mode 100644 new mode 100755 index 07eac36..48e2ae1 --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/TestCarMapper.java +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/TestCarMapper.java @@ -1,18 +1,18 @@ /** -* 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. -*/ + * 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.modulars.gentest.carinfo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; @@ -21,12 +21,12 @@ import org.apache.ibatis.annotations.Param; import org.opsli.modulars.gentest.carinfo.entity.TestCar; /** - * 汽车信息 Mapper + * 测试汽车 Mapper * * @author Parker - * @date 2020-12-20 20:12:57 + * @date 2022-08-06 23:53:30 */ @Mapper public interface TestCarMapper extends BaseMapper { -} +} \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/xml/TestCarMapper.xml b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/xml/TestCarMapper.xml old mode 100644 new mode 100755 index c4c0390..897b98a --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/xml/TestCarMapper.xml +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/mapper/xml/TestCarMapper.xml @@ -3,4 +3,4 @@ - + \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/ITestCarService.java b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/ITestCarService.java old mode 100644 new mode 100755 index 7e8ef8e..4f0503b --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/ITestCarService.java +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/ITestCarService.java @@ -1,18 +1,18 @@ /** -* 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. -*/ + * 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.modulars.gentest.carinfo.service; import org.opsli.core.base.service.interfaces.CrudServiceInterface; @@ -22,11 +22,11 @@ import org.opsli.modulars.gentest.carinfo.entity.TestCar; import org.opsli.api.wrapper.gentest.carinfo.TestCarModel; /** - * 汽车信息 Service + * 测试汽车 Service * * @author Parker - * @date 2020-12-20 20:12:57 + * @date 2022-08-06 23:53:30 */ public interface ITestCarService extends CrudServiceInterface { -} +} \ No newline at end of file diff --git a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/impl/TestCarServiceImpl.java b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/impl/TestCarServiceImpl.java old mode 100644 new mode 100755 index 5675fb4..18050c7 --- a/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/impl/TestCarServiceImpl.java +++ b/opsli-modulars/opsli-modulars-test/src/main/java/org/opsli/modulars/gentest/carinfo/service/impl/TestCarServiceImpl.java @@ -1,18 +1,18 @@ /** -* 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. -*/ + * 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.modulars.gentest.carinfo.service.impl; @@ -26,11 +26,12 @@ import org.opsli.api.wrapper.gentest.carinfo.TestCarModel; import org.opsli.modulars.gentest.carinfo.service.ITestCarService; import org.opsli.modulars.gentest.carinfo.mapper.TestCarMapper; + /** - * 汽车信息 Service Impl + * 测试汽车 Service Impl * * @author Parker - * @date 2020-12-20 20:12:57 + * @date 2022-08-06 23:53:30 */ @Service public class TestCarServiceImpl extends CrudServiceImpl @@ -39,4 +40,4 @@ public class TestCarServiceImpl extends CrudServiceImpl -* 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. -*/ + * 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.modulars.gentest.carinfo.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.opsli.common.annotation.RequiresPermissionsCus; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; @@ -32,18 +28,22 @@ import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; +import org.springframework.security.access.prepost.PreAuthorize; +import org.opsli.core.log.enums.*; +import org.opsli.core.log.annotation.OperateLogger; import org.opsli.modulars.gentest.carinfo.entity.TestCar; import org.opsli.api.wrapper.gentest.carinfo.TestCarModel; import org.opsli.modulars.gentest.carinfo.service.ITestCarService; import org.opsli.api.web.gentest.carinfo.TestCarRestApi; +import java.util.Optional; + /** - * 汽车信息 Controller + * 测试汽车 Controller * * @author Parker - * @date 2020-12-20 20:12:57 + * @date 2022-08-06 23:58:27 */ @Api(tags = TestCarRestApi.TITLE) @Slf4j @@ -53,150 +53,151 @@ public class TestCarRestController extends BaseRestController get(TestCarModel model) { - model = IService.get(model); - return ResultVo.success(model); + public ResultWrapper get(TestCarModel model) { + // 如果系统内部调用 则直接查数据库 + if(model != null && model.getIzApi() != null && model.getIzApi()){ + model = IService.get(model); + } + return ResultWrapper.getSuccessResultWrapper(model); } /** - * 汽车信息 查询分页 - * @param pageNo 当前页 - * @param pageSize 每页条数 - * @param request request - * @return ResultVo - */ + * 测试汽车 查询分页 + * @param pageNo 当前页 + * @param pageSize 每页条数 + * @param request request + * @return ResultWrapper + */ @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器") - @RequiresPermissions("gentest_carinfo_select") + @PreAuthorize("hasAuthority('gentest_carinfo_select')") @Override - public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - QueryBuilder queryBuilder = new WebQueryBuilder<>(TestCar.class, request.getParameterMap()); + QueryBuilder queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(), request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** - * 汽车信息 新增 - * @param model 模型 - * @return ResultVo - */ - @ApiOperation(value = "新增汽车信息数据", notes = "新增汽车信息数据") - @RequiresPermissions("gentest_carinfo_insert") - @EnableLog + * 测试汽车 新增 + * @param model 模型 + * @return ResultWrapper + */ + @ApiOperation(value = "新增测试汽车数据", notes = "新增测试汽车数据") + @PreAuthorize("hasAuthority('gentest_carinfo_insert')") + @OperateLogger(description = "新增测试汽车数据", + module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(TestCarModel model) { + public ResultWrapper insert(TestCarModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增汽车信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增测试汽车成功"); } /** - * 汽车信息 修改 - * @param model 模型 - * @return ResultVo - */ - @ApiOperation(value = "修改汽车信息数据", notes = "修改汽车信息数据") - @RequiresPermissions("gentest_carinfo_update") - @EnableLog + * 测试汽车 修改 + * @param model 模型 + * @return ResultWrapper + */ + @ApiOperation(value = "修改测试汽车数据", notes = "修改测试汽车数据") + @PreAuthorize("hasAuthority('gentest_carinfo_update')") + @OperateLogger(description = "修改测试汽车数据", + module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(TestCarModel model) { + public ResultWrapper update(TestCarModel model) { // 调用修改方法 IService.update(model); - return ResultVo.success("修改汽车信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改测试汽车成功"); } /** - * 汽车信息 删除 - * @param id ID - * @return ResultVo - */ - @ApiOperation(value = "删除汽车信息数据", notes = "删除汽车信息数据") - @RequiresPermissions("gentest_carinfo_update") - @EnableLog + * 测试汽车 删除 + * @param id ID + * @return ResultVo + */ + @ApiOperation(value = "删除测试汽车数据", notes = "删除测试汽车数据") + @PreAuthorize("hasAuthority('gentest_carinfo_delete')") + @OperateLogger(description = "删除测试汽车数据", + module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ IService.delete(id); - return ResultVo.success("删除汽车信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除测试汽车成功"); } /** - * 汽车信息 批量删除 - * @param ids ID 数组 - * @return ResultVo - */ - @ApiOperation(value = "批量删除汽车信息数据", notes = "批量删除汽车信息数据") - @RequiresPermissions("gentest_carinfo_update") - @EnableLog + * 测试汽车 批量删除 + * @param ids ID 数组 + * @return ResultVo + */ + @ApiOperation(value = "批量删除测试汽车数据", notes = "批量删除测试汽车数据") + @PreAuthorize("hasAuthority('gentest_carinfo_delete')") + @OperateLogger(description = "批量删除测试汽车数据", + module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除汽车信息成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除测试汽车成功"); } - /** - * 汽车信息 Excel 导出 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("gentest_carinfo_export") - @EnableLog + * 测试汽车 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('gentest_carinfo_export', 'gentest_carinfo_import')") @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(TestCarRestApi.SUB_TITLE, queryBuilder.build(), response, method); + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, TestCarRestApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); } + /** - * 汽车信息 Excel 导入 - * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("gentest_carinfo_import") - @EnableLog + * 测试汽车 Excel 导出 + * @param response response + */ + @ApiOperation(value = "导出Excel", notes = "导出Excel") + @PreAuthorize("hasAuthority('gentest_carinfo_export')") + @OperateLogger(description = "测试汽车 导出Excel", + module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.SELECT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } /** - * 汽车信息 Excel 下载导入模版 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("gentest_carinfo_import") + * 测试汽车 Excel 导入 + * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 + * @param request 文件流 request + * @return ResultVo + */ + @ApiOperation(value = "导入Excel", notes = "导入Excel") + @PreAuthorize("hasAuthority('gentest_carinfo_import')") + @OperateLogger(description = "测试汽车 Excel 导入", + module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.INSERT, db = true) @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(TestCarRestApi.SUB_TITLE, response, method); + public ResultWrapper importExcel(MultipartHttpServletRequest request) { + return super.importExcel(request); } } 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 2bd1972..61155a2 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 @@ -1,44 +1,43 @@ /** -* 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. -*/ + * 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.modulars.gentest.user.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import io.swagger.annotations.Api; -import org.opsli.common.annotation.RequiresPermissionsCus; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; +import org.opsli.api.web.gentest.user.TestUserRestApi; +import org.opsli.api.wrapper.gentest.user.TestUserModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.opsli.modulars.gentest.user.entity.TestUser; -import org.opsli.api.wrapper.gentest.user.TestUserModel; import org.opsli.modulars.gentest.user.service.ITestUserService; -import org.opsli.api.web.gentest.user.TestUserRestApi; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.multipart.MultipartHttpServletRequest; -import java.lang.reflect.Method; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Optional; /** * 某系统用户 Controller @@ -50,146 +49,155 @@ import java.lang.reflect.Method; @Slf4j @ApiRestController("/{ver}/gentest/user") public class TestUserRestController extends BaseRestController - implements TestUserRestApi { + implements TestUserRestApi { /** - * 用户 查一条 - * @param model 模型 - * @return ResultVo - */ + * 用户 查一条 + * @param model 模型 + * @return ResultWrapper + */ @ApiOperation(value = "获得单条用户", notes = "获得单条用户 - ID") - @RequiresPermissions("gentest_user_select") + @PreAuthorize("hasAuthority('gentest_user_select')") @Override - public ResultVo get(TestUserModel model) { + public ResultWrapper get(TestUserModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** - * 用户 查询分页 - * @param pageNo 当前页 - * @param pageSize 每页条数 - * @param request request - * @return ResultVo - */ + * 用户 查询分页 + * @param pageNo 当前页 + * @param pageSize 每页条数 + * @param request request + * @return ResultWrapper + */ @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器") - @RequiresPermissions("gentest_user_select") + @PreAuthorize("hasAuthority('gentest_user_select')") @Override - public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { QueryBuilder queryBuilder = new WebQueryBuilder<>(TestUser.class, request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** - * 用户 新增 - * @param model 模型 - * @return ResultVo - */ + * 用户 新增 + * @param model 模型 + * @return ResultWrapper + */ @ApiOperation(value = "新增用户数据", notes = "新增用户数据") - @RequiresPermissions("gentest_user_insert") - @EnableLog + @PreAuthorize("hasAuthority('gentest_user_insert')") + @OperateLogger(description = "新增用户数据", + module = ModuleEnum.MODULE_TEST_USER, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(TestUserModel model) { + public ResultWrapper insert(TestUserModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增用户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增用户成功"); } /** - * 用户 修改 - * @param model 模型 - * @return ResultVo - */ + * 用户 修改 + * @param model 模型 + * @return ResultWrapper + */ @ApiOperation(value = "修改用户数据", notes = "修改用户数据") - @RequiresPermissions("gentest_user_update") - @EnableLog + @PreAuthorize("hasAuthority('gentest_user_update')") + @OperateLogger(description = "修改用户数据", + module = ModuleEnum.MODULE_TEST_USER, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(TestUserModel model) { + public ResultWrapper update(TestUserModel model) { // 调用修改方法 IService.update(model); - return ResultVo.success("修改用户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改用户成功"); } /** - * 用户 删除 - * @param id ID - * @return ResultVo - */ + * 用户 删除 + * @param id ID + * @return ResultWrapper + */ @ApiOperation(value = "删除用户数据", notes = "删除用户数据") - @RequiresPermissions("gentest_user_update") - @EnableLog + @PreAuthorize("hasAuthority('gentest_user_update')") + @OperateLogger(description = "删除用户数据", + module = ModuleEnum.MODULE_TEST_USER, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ IService.delete(id); - return ResultVo.success("删除用户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除用户成功"); } /** - * 用户 批量删除 - * @param ids ID 数组 - * @return ResultVo - */ + * 用户 批量删除 + * @param ids ID 数组 + * @return ResultWrapper + */ @ApiOperation(value = "批量删除用户数据", notes = "批量删除用户数据") - @RequiresPermissions("gentest_user_update") - @EnableLog + @PreAuthorize("hasAuthority('gentest_user_update')") + @OperateLogger(description = "批量删除用户数据", + module = ModuleEnum.MODULE_TEST_USER, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除用户成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除用户成功"); } + /** - * 用户 Excel 导出 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("gentest_user_export") - @EnableLog + * 用户 Excel 导出认证 + * + * @param type 类型 + * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('gentest_user_export', 'gentest_user_import')") @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(TestUserRestApi.SUB_TITLE, queryBuilder.build(), response, method); + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, TestUserRestApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); } + /** - * 用户 Excel 导入 - * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("gentest_user_import") - @EnableLog + * 用户 Excel 导出 + * @param response response + */ + @ApiOperation(value = "导出Excel", notes = "导出Excel") + @PreAuthorize("hasAuthority('gentest_user_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_TEST_USER, operationType = OperationTypeEnum.SELECT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } /** - * 用户 Excel 下载导入模版 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("gentest_user_import") + * 用户 Excel 导入 + * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 + * @param request 文件流 request + * @return ResultWrapper + */ + @ApiOperation(value = "导入Excel", notes = "导入Excel") + @PreAuthorize("hasAuthority('gentest_user_import')") + @OperateLogger(description = "用户 Excel 导入", + module = ModuleEnum.MODULE_TEST_USER, operationType = OperationTypeEnum.INSERT, db = true) @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(TestUserRestApi.SUB_TITLE, response, method); + public ResultWrapper importExcel(MultipartHttpServletRequest request) { + return super.importExcel(request); } + } 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 61524b5..10508f7 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 @@ -1,28 +1,28 @@ package org.opsli.modulars.test.web; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ReflectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; +import org.opsli.api.base.result.ResultWrapper; import org.opsli.api.web.test.TestRestApi; import org.opsli.api.wrapper.test.TestModel; import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.core.base.controller.BaseRestController; +import org.opsli.core.log.annotation.OperateLogger; +import org.opsli.core.log.enums.ModuleEnum; +import org.opsli.core.log.enums.OperationTypeEnum; import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.modulars.test.entity.TestEntity; import org.opsli.modulars.test.service.ITestService; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; +import java.util.Optional; /** * 测试类 Controller @@ -39,14 +39,14 @@ public class TestRestController extends BaseRestController get(TestModel model) { + public ResultWrapper get(TestModel model) { model = IService.get(model); - return ResultVo.success(model); + return ResultWrapper.getSuccessResultWrapper(model); } /** @@ -54,124 +54,133 @@ public class TestRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { + public ResultWrapper findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { QueryBuilder queryBuilder = new WebQueryBuilder<>(TestEntity.class, request.getParameterMap()); Page page = new Page<>(pageNo, pageSize); page.setQueryWrapper(queryBuilder.build()); page = IService.findPage(page); - return ResultVo.success(page.getPageData()); + return ResultWrapper.getSuccessResultWrapper(page.getPageData()); } /** * 测试 新增 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "新增测试", notes = "新增测试") - @RequiresPermissions("gentest_test_insert") - @EnableLog + @PreAuthorize("hasAuthority('gentest_test_insert')") + @OperateLogger(description = "新增测试", + module = ModuleEnum.MODULE_TEST, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo insert(TestModel model) { + public ResultWrapper insert(TestModel model) { // 调用新增方法 IService.insert(model); - return ResultVo.success("新增测试成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("新增测试成功"); } /** * 测试 修改 * @param model 模型 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "修改测试", notes = "修改测试") - @RequiresPermissions("gentest_test_update") - @EnableLog + @PreAuthorize("hasAuthority('gentest_test_update')") + @OperateLogger(description = "修改测试", + module = ModuleEnum.MODULE_TEST, operationType = OperationTypeEnum.UPDATE, db = true) @Override - public ResultVo update(TestModel model) { + public ResultWrapper update(TestModel model) { // 调用修改方法 IService.update(model); - return ResultVo.success("修改测试成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("修改测试成功"); } /** * 测试 删除 * @param id ID - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "删除测试数据", notes = "删除测试数据") - @RequiresPermissions("gentest_test_delete") - @EnableLog + @PreAuthorize("hasAuthority('gentest_test_delete')") + @OperateLogger(description = "测试 删除", + module = ModuleEnum.MODULE_TEST, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo del(String id){ + public ResultWrapper del(String id){ IService.delete(id); - return ResultVo.success("删除测试成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("删除测试成功"); } /** * 测试 批量删除 * @param ids ID 数组 - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "批量删除测试数据", notes = "批量删除测试数据") - @RequiresPermissions("gentest_test_delete") - @EnableLog + @PreAuthorize("hasAuthority('gentest_test_delete')") + @OperateLogger(description = "测试 批量删除", + module = ModuleEnum.MODULE_TEST, operationType = OperationTypeEnum.DELETE, db = true) @Override - public ResultVo delAll(String ids){ + public ResultWrapper delAll(String ids){ String[] idArray = Convert.toStrArray(ids); IService.deleteAll(idArray); - return ResultVo.success("批量删除测试成功"); + return ResultWrapper.getSuccessResultWrapperByMsg("批量删除测试成功"); } /** - * 测试 Excel 导出 + * 测试 Excel 导出认证 + * + * @param type 类型 * @param request request + */ + @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证") + @PreAuthorize("hasAnyAuthority('gentest_test_export', 'gentest_test_import')") + @Override + public ResultWrapper exportExcelAuth(String type, HttpServletRequest request) { + Optional certificateOptional = + super.excelExportAuth(type, TestRestApi.SUB_TITLE, request); + if(!certificateOptional.isPresent()){ + return ResultWrapper.getErrorResultWrapper(); + } + return ResultWrapper.getSuccessResultWrapper(certificateOptional.get()); + } + + + /** + * 测试 Excel 导出 * @param response response */ @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("gentest_test_export") - @EnableLog + @PreAuthorize("hasAuthority('gentest_test_export')") + @OperateLogger(description = "导出Excel", + module = ModuleEnum.MODULE_TEST, operationType = OperationTypeEnum.SELECT, db = true) @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(TestRestApi.SUB_TITLE, queryBuilder.build(), response, method); + public void exportExcel(String certificate, HttpServletResponse response) { + // 导出Excel + super.excelExport(certificate, response); } /** * 测试 Excel 导入 * @param request 文件流 request - * @return ResultVo + * @return ResultWrapper */ @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("gentest_test_import") - @EnableLog + @PreAuthorize("hasAuthority('gentest_test_import')") + @OperateLogger(description = "测试 Excel 导入", + module = ModuleEnum.MODULE_TEST, operationType = OperationTypeEnum.INSERT, db = true) @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { + public ResultWrapper importExcel(MultipartHttpServletRequest request) { return super.importExcel(request); } - /** - * 测试 Excel 下载导入模版 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("gentest_test_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(TestRestApi.SUB_TITLE, response, method); - } - } diff --git a/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/RedisPlugin.java b/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/RedisPlugin.java index 4bf9cf7..7f29c79 100644 --- a/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/RedisPlugin.java +++ b/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/RedisPlugin.java @@ -30,10 +30,7 @@ import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Component; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; /** @@ -150,6 +147,25 @@ public class RedisPlugin { return ret != null && ret; } + /** + * 设置缓存有效时间 + * + * @param key 主键 + * @param date 失效时间 + * @return boolean + */ + public boolean expireAt(String key, Date date) { + Boolean ret = null; + try { + if(null != date){ + ret = redisTemplate.expireAt(key, date); + } + }catch (Exception e){ + log.error(e.getMessage(),e); + } + return ret != null && ret; + } + /** * 获得缓存有效时间 * diff --git a/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/jsonserializer/FastJson2JsonRedisSerializer.java b/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/jsonserializer/FastJson2JsonRedisSerializer.java index 427c11b..39bb886 100644 --- a/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/jsonserializer/FastJson2JsonRedisSerializer.java +++ b/opsli-plugins/opsli-plugins-redis/src/main/java/org/opsli/plugins/redis/jsonserializer/FastJson2JsonRedisSerializer.java @@ -15,7 +15,7 @@ import java.nio.charset.StandardCharsets; * FastJson2JsonRedisSerializer * Redis使用FastJson序列化 * - * @author 周鹏程 + * @author Parker * @date 2021年6月1日13:57:02 */ @Slf4j @@ -110,4 +110,4 @@ public class FastJson2JsonRedisSerializer implements RedisSerializer { return (T) obj; } -} \ No newline at end of file +} diff --git a/opsli-plugins/opsli-plugins-security/pom.xml b/opsli-plugins/opsli-plugins-security/pom.xml new file mode 100644 index 0000000..823bc79 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/pom.xml @@ -0,0 +1,25 @@ + + + + opsli-plugins + org.opsliframework.boot + 1.0.0 + ../pom.xml + + + 4.0.0 + opsli-plugins-security + ${project.parent.version} + + + + + org.springframework.boot + spring-boot-starter-security + + + + + diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/JwtConstants.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/JwtConstants.java new file mode 100644 index 0000000..b9fe5a1 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/JwtConstants.java @@ -0,0 +1,48 @@ +/** + * 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.plugins.security; + + +/** + * JWT 常量 + * + * @author Parker + * @date 2021年12月22日16:18:15 + */ +public final class JwtConstants { + + /** 请求头的默认前缀 */ + public static final String TOKEN_HEAD = "Bearer "; + /** jwt token 的认证头部 */ + public static final String TOKEN_HEADER = "T-Authorization"; + /** jwt 刷新token 的认证头部 */ + public static final String REFRESH_TOKEN_HEADER = "R-Authorization"; + /** FORM 表单头部 */ + public static final String FROM_HEADER = "x-from"; + + public static final String JWT_CLAIM_TAG = "tag"; + public static final String JWT_CLAIM_KEY_ID = "uid"; + public static final String JWT_CLAIM_KEY_USER_NAME = "username"; + public static final String JWT_CLAIM_KEY_NICK_NAME = "nickname"; + public static final String JWT_CLAIM_KEY_PHONE = "phone"; + public static final String JWT_CLAIM_KEY_EMAIL = "email"; + public static final String JWT_CLAIM_KEY_LOGIN_FROM = "loginFrom"; + public static final String JWT_CLAIM_KEY_LOGIN_IP = "loginIp"; + + public static final Integer JWT_SIGNATURE_DELAY = -5; + + private JwtConstants(){} +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/LoginUserInfo.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/LoginUserInfo.java new file mode 100644 index 0000000..a77fdf9 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/LoginUserInfo.java @@ -0,0 +1,59 @@ +/** + * 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.plugins.security; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 当前登录用户信息 + * + * @author Parker + * @date 2021年12月22日16:22:37 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class LoginUserInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 用户ID */ + private String uid; + + /** 用户名 */ + private String username; + + /** 用户昵称 */ + private String nickname; + + /** 手机 */ + private String mobile; + + /** 邮箱 */ + private String email; + + /** 登录来源: 0:PC端;1:APP-安卓 2:APP-IOS 3:小程序 */ + private String loginFrom; + + /** 登录ip */ + private String loginIp; +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/SecurityConfig.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/SecurityConfig.java new file mode 100644 index 0000000..49118bb --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/SecurityConfig.java @@ -0,0 +1,61 @@ +/** + * 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.plugins.security; + +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.security.properties.AuthProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * Redisson自动化配置 + * + * @author Parker + * @date 2019/6/19 下午11:55 + */ +@Slf4j +@Configuration +@EnableConfigurationProperties(AuthProperties.class) +public class SecurityConfig { + + /** + * org.opsli.plugins.security.checker.DefaultPostAuthenticationChecks\ + * org.opsli.plugins.security.checker.DefaultPreAuthenticationChecks\ + * org.opsli.plugins.security.eventbus.SpringSecurityEventBus\ + * org.opsli.plugins.security.handler.AuthErrorHandler\ + * org.opsli.plugins.security.handler.AuthServiceErrorHandler\ + * org.opsli.plugins.security.handler.OtherErrorHandler\ + * org.opsli.plugins.security.handler.SecurityErrorHandler\ + * org.opsli.plugins.security.provider.EmailCodeAuthenticationProvider\ + * org.opsli.plugins.security.provider.EmailPasswordAuthenticationProvider\ + * org.opsli.plugins.security.provider.MobileCodeAuthenticationProvider\ + * org.opsli.plugins.security.provider.MobilePasswordAuthenticationProvider\ + * org.opsli.plugins.security.provider.UsernamePasswordAuthenticationProvider\ + * org.opsli.plugins.security.service.LoadUserDetailServiceFactory + */ + + /** + * 密码解析器 + */ + @Bean + public PasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } +} + diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/UserDetailModel.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/UserDetailModel.java new file mode 100644 index 0000000..fdc7881 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/UserDetailModel.java @@ -0,0 +1,90 @@ +/** + * 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.plugins.security; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; + +/** + * @author Parker + * @date 2022-07-14 6:04 PM + **/ +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class UserDetailModel implements UserDetails { + + /** 用户名 */ + private String username; + /** 密码 */ + private String password; + + /** 账户未过期 */ + private boolean accountNonExpired; + + /** 账户未锁定 */ + private boolean accountNonLocked; + + /** 凭证未过期 */ + private boolean credentialsNonExpired; + + /** 未启用 */ + private boolean enabled; + + /** 授权信息 */ + private List authorities; + + @Override + public Collection getAuthorities() { + return this.authorities; + } + + @Override + public String getPassword() { + return this.password; + } + + @Override + public String getUsername() { + return this.username; + } + + @Override + public boolean isAccountNonExpired() { + return this.accountNonExpired; + } + + @Override + public boolean isAccountNonLocked() { + return this.accountNonLocked; + } + + @Override + public boolean isCredentialsNonExpired() { + return this.credentialsNonExpired; + } + + @Override + public boolean isEnabled() { + return this.enabled; + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/AfterAuthenticationToken.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/AfterAuthenticationToken.java new file mode 100644 index 0000000..8998f96 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/AfterAuthenticationToken.java @@ -0,0 +1,87 @@ +/** + * 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.plugins.security.authentication; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * 认证后 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +public class AfterAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + /** 认证主体 */ + private final Object principal; + /** 授权信息 */ + private Object credentials; + + /** + * 没有经过验证时,权限位空,setAuthenticated设置为不可信令牌 + * @param principal + * @param credentials + */ + public AfterAuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + /** + * 已认证后,将权限加上,setAuthenticated设置为可信令牌 + * @param principal + * @param credentials + * @param authorities + */ + public AfterAuthenticationToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + Assert.isTrue(!isAuthenticated, + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + this.credentials = null; + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/EmailCodeAuthenticationToken.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/EmailCodeAuthenticationToken.java new file mode 100644 index 0000000..37c73ef --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/EmailCodeAuthenticationToken.java @@ -0,0 +1,87 @@ +/** + * 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.plugins.security.authentication; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * 邮箱验证码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +public class EmailCodeAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + /** 邮箱账号 */ + private final Object principal; + /** 邮箱验证码 */ + private Object credentials; + + /** + * 没有经过验证时,权限位空,setAuthenticated设置为不可信令牌 + * @param principal + * @param credentials + */ + public EmailCodeAuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + /** + * 已认证后,将权限加上,setAuthenticated设置为可信令牌 + * @param principal + * @param credentials + * @param authorities + */ + public EmailCodeAuthenticationToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + Assert.isTrue(!isAuthenticated, + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + this.credentials = null; + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/EmailPasswordAuthenticationToken.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/EmailPasswordAuthenticationToken.java new file mode 100644 index 0000000..f0ea345 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/EmailPasswordAuthenticationToken.java @@ -0,0 +1,87 @@ +/** + * 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.plugins.security.authentication; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * 邮箱密码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +public class EmailPasswordAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + /** 邮箱账号 */ + private final Object principal; + /** 用户密码 */ + private Object credentials; + + /** + * 没有经过验证时,权限位空,setAuthenticated设置为不可信令牌 + * @param principal + * @param credentials + */ + public EmailPasswordAuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + /** + * 已认证后,将权限加上,setAuthenticated设置为可信令牌 + * @param principal + * @param credentials + * @param authorities + */ + public EmailPasswordAuthenticationToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + Assert.isTrue(!isAuthenticated, + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + this.credentials = null; + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/MobileCodeAuthenticationToken.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/MobileCodeAuthenticationToken.java new file mode 100644 index 0000000..198fcc6 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/MobileCodeAuthenticationToken.java @@ -0,0 +1,87 @@ +/** + * 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.plugins.security.authentication; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * 手机验证码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +public class MobileCodeAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + /** 手机号 */ + private final Object principal; + /** 验证码 */ + private Object credentials; + + /** + * 没有经过验证时,权限位空,setAuthenticated设置为不可信令牌 + * @param principal + * @param credentials + */ + public MobileCodeAuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + /** + * 已认证后,将权限加上,setAuthenticated设置为可信令牌 + * @param principal + * @param credentials + * @param authorities + */ + public MobileCodeAuthenticationToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + Assert.isTrue(!isAuthenticated, + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + this.credentials = null; + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/MobilePasswordAuthenticationToken.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/MobilePasswordAuthenticationToken.java new file mode 100644 index 0000000..9d4cd91 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/authentication/MobilePasswordAuthenticationToken.java @@ -0,0 +1,87 @@ +/** + * 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.plugins.security.authentication; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * 手机密码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +public class MobilePasswordAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + /** 手机账号 */ + private final Object principal; + /** 用户密码 */ + private Object credentials; + + /** + * 没有经过验证时,权限位空,setAuthenticated设置为不可信令牌 + * @param principal + * @param credentials + */ + public MobilePasswordAuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + /** + * 已认证后,将权限加上,setAuthenticated设置为可信令牌 + * @param principal + * @param credentials + * @param authorities + */ + public MobilePasswordAuthenticationToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + Assert.isTrue(!isAuthenticated, + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + this.credentials = null; + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/checker/DefaultPostAuthenticationChecks.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/checker/DefaultPostAuthenticationChecks.java new file mode 100644 index 0000000..9064bbd --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/checker/DefaultPostAuthenticationChecks.java @@ -0,0 +1,39 @@ +/** + * 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.plugins.security.checker; + +import org.springframework.security.authentication.CredentialsExpiredException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsChecker; +import org.springframework.stereotype.Component; + +/** + * 用户凭证过期情况 检查 + * + * @author Parker + * @date 2022年07月18日16:18:37 + */ +@Component +public class DefaultPostAuthenticationChecks implements UserDetailsChecker { + + @Override + public void check(UserDetails user) { + if (!user.isCredentialsNonExpired()) { + throw new CredentialsExpiredException("User credentials has expired"); + } + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/checker/DefaultPreAuthenticationChecks.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/checker/DefaultPreAuthenticationChecks.java new file mode 100644 index 0000000..07c15a0 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/checker/DefaultPreAuthenticationChecks.java @@ -0,0 +1,47 @@ +/** + * 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.plugins.security.checker; + +import org.springframework.security.authentication.AccountExpiredException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.LockedException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsChecker; +import org.springframework.stereotype.Component; + +/** + * 用户其他附属条件检查 + * + * @author Parker + * @date 2022年07月18日16:18:37 + */ +@Component +public class DefaultPreAuthenticationChecks implements UserDetailsChecker { + + @Override + public void check(UserDetails user) { + if (!user.isAccountNonLocked()) { + throw new LockedException("User account is locked"); + } + if (!user.isEnabled()) { + throw new DisabledException("User is disabled"); + } + if (!user.isAccountNonExpired()) { + throw new AccountExpiredException("User account has expired"); + } + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/AbstractSpringSecuritySecurityEventBus.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/AbstractSpringSecuritySecurityEventBus.java new file mode 100644 index 0000000..70e9fa0 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/AbstractSpringSecuritySecurityEventBus.java @@ -0,0 +1,43 @@ +/** + * 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.plugins.security.eventbus; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * EventBus 与 Spring 打通桥梁 + * + * @author Parker + * @date 2021年12月7日10:39:16 + */ +public abstract class AbstractSpringSecuritySecurityEventBus implements ISecurityEventBus, ApplicationContextAware { + private ApplicationContext context; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.context = applicationContext; + this.scanConsumer(null); + } + + @Override + public void scanConsumer(String packageName) { + context.getBeansOfType(ISecurityEventConsumer.class).forEach((k, v)->{ + this.addConsumer(v); + }); + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/ISecurityEventBus.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/ISecurityEventBus.java new file mode 100644 index 0000000..25a0645 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/ISecurityEventBus.java @@ -0,0 +1,48 @@ +/** + * 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.plugins.security.eventbus; + +/** + * EventBus 接口 + * + * @author Parker + * @date 2021年12月7日10:38:24 + */ +public interface ISecurityEventBus { + /** + * 发布事件 + * @param event 事件实体 + */ + void post(Object event); + + /** + * 添加消费者 + * @param obj 消费者对象,默认以class为key + */ + void addConsumer(Object obj); + + /** + * 移除消费者 + * @param obj 消费者对象,默认以class为key + */ + void removeConsumer(Object obj); + + /** + * 扫描消费者 + * @param packageName 扫描包 + */ + void scanConsumer(String packageName); +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/ISecurityEventConsumer.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/ISecurityEventConsumer.java new file mode 100644 index 0000000..391e079 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/ISecurityEventConsumer.java @@ -0,0 +1,32 @@ +/** + * 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.plugins.security.eventbus; + +/** + * EventBus 消费者接口 + * + * @author Parker + * @date 2020/9/25 12:19 + */ +public interface ISecurityEventConsumer { + + /** + * 消费者事件 + * @param event 事件 + */ + void consumer(T event); + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/SpringSecurityEventBus.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/SpringSecurityEventBus.java new file mode 100644 index 0000000..5a4a5e1 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventbus/SpringSecurityEventBus.java @@ -0,0 +1,74 @@ +/** + * 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.plugins.security.eventbus; + +import com.google.common.eventbus.AsyncEventBus; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.SubscriberExceptionContext; +import com.google.common.eventbus.SubscriberExceptionHandler; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 操作日志事件 总线 + * @author Parker + * @date 2021年12月7日10:42:39 + */ +@Slf4j +@Component +public class SpringSecurityEventBus extends AbstractSpringSecuritySecurityEventBus + implements SubscriberExceptionHandler { + + private final EventBus eventBus; + + public SpringSecurityEventBus() { + // 异步事件配置线程池 + eventBus = new AsyncEventBus( + new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, + new LinkedBlockingDeque<>(1024), + new ThreadFactoryBuilder() + .setNameFormat("Spring-Security-Event-Bus").build(), + new ThreadPoolExecutor.CallerRunsPolicy()) + , this + ); + } + + @Override + public void post(Object event) { + eventBus.post(event); + } + + @Override + public void addConsumer(Object obj) { + eventBus.register(obj); + } + + @Override + public void removeConsumer(Object obj) { + eventBus.unregister(obj); + } + + @Override + public void handleException(Throwable exception, SubscriberExceptionContext context) { + log.error("user event handler exception", exception); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventdto/BadCredentials.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventdto/BadCredentials.java new file mode 100644 index 0000000..6c1b350 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/eventdto/BadCredentials.java @@ -0,0 +1,41 @@ +/** + * 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.plugins.security.eventdto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 错误凭证 + * + * @author Parker + * @date 2022-07-16 8:14 PM + **/ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class BadCredentials { + + /** 主键 */ + private String principal; + + /** 凭证 */ + private String credentials; + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/AuthException.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/AuthException.java new file mode 100644 index 0000000..9e142c0 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/AuthException.java @@ -0,0 +1,65 @@ +/** + * 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.plugins.security.exception; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.opsli.plugins.security.exception.errorcode.BaseAuthMsg; + +/** + * 认证异常 + * + * @author Parker + * @date 2020-09-13 19:41 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class AuthException extends RuntimeException{ + + private Integer code; + + private String description; + + private String errorMessage; + + public AuthException(Integer code, String errorMessage) { + super(errorMessage); + this.code = code; + this.errorMessage = errorMessage; + } + + public AuthException(Integer code, String errorMessage, Throwable e) { + super(errorMessage, e); + this.code = code; + this.errorMessage = errorMessage; + } + + public AuthException(BaseAuthMsg msg) { + super(msg.getMessage()); + this.code = msg.getCode(); + this.description = msg.getDescription(); + this.errorMessage = msg.getMessage(); + } + + public AuthException(BaseAuthMsg msg, Throwable e) { + super(msg.getMessage(), e); + this.code = msg.getCode(); + this.description = msg.getDescription(); + this.errorMessage = msg.getMessage(); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/AuthServiceException.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/AuthServiceException.java new file mode 100644 index 0000000..6a9ec9a --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/AuthServiceException.java @@ -0,0 +1,65 @@ +/** + * 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.plugins.security.exception; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.opsli.plugins.security.exception.errorcode.BaseAuthMsg; + +/** + * 认证服务异常 + * + * @author Parker + * @date 2020-09-13 19:41 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class AuthServiceException extends RuntimeException{ + + private Integer code; + + private String description; + + private String errorMessage; + + public AuthServiceException(Integer code, String errorMessage) { + super(errorMessage); + this.code = code; + this.errorMessage = errorMessage; + } + + public AuthServiceException(Integer code, String errorMessage, Throwable e) { + super(errorMessage, e); + this.code = code; + this.errorMessage = errorMessage; + } + + public AuthServiceException(BaseAuthMsg msg) { + super(msg.getMessage()); + this.code = msg.getCode(); + this.description = msg.getDescription(); + this.errorMessage = msg.getMessage(); + } + + public AuthServiceException(BaseAuthMsg msg, Throwable e) { + super(msg.getMessage(), e); + this.code = msg.getCode(); + this.description = msg.getDescription(); + this.errorMessage = msg.getMessage(); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/errorcode/AuthErrorCodeEnum.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/errorcode/AuthErrorCodeEnum.java new file mode 100644 index 0000000..2764704 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/errorcode/AuthErrorCodeEnum.java @@ -0,0 +1,84 @@ +/** + * 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.plugins.security.exception.errorcode; + +/** + * 业务状态码 + * 组成描述: 错误级别(1位) + 模块标识(2位) + 具体错误码(3位) + * 0011000 + * + * 0 为通用正确 一切OK + * -1 为通用错误 + * + * 错误级别 + * + * 1 错误来源于用户 + * 2 错误来源于当前系统 + * 3 示错误来源于第三方服务 + * + * 模块标识 + * 00 - 公共模块 + * + * @author Parker + * @date 2020-09-13 19:36 + */ +public enum AuthErrorCodeEnum implements BaseAuthMsg { + + /** 认证服务 */ + + AUTH_NOT_FIND_USER_SERVICE(100201, "未加载到获取用户Service", "系统故障请稍微再试,故障码:10201"), + AUTH_NOT_FIND_USER(100202, "未获取到用户", "认证失败"), + AUTH_WRONG_PASSWORD(100203, "凭证错误", "密码不正确!"), + AUTH_ACCOUNT_LOCKED(100204, "用户账号已锁定", "用户账号已锁定,请联系管理员"), + AUTH_ACCOUNT_DISABLED(100205, "用户账号未启用", "用户账号未启用,请联系管理员"), + AUTH_ACCOUNT_EXPIRED(100206, "用户账号已过期", "用户账号已过期,请联系管理员"), + AUTH_ACCOUNT_CREDENTIALS_EXPIRED(100207, "用户密码凭证已过期", "密码凭证已过期,请修改密码"), + + AUTH_CREDENTIALS_INVALID(401, "凭证无效", "凭证已过期,请重新登陆"), + AUTH_AUTH_INVALID(401, "认证无效", "认证失败,请重新登陆"), + + AUTH_NO_ACCESS(100210, "无权访问", "权限不足,请联系管理员"), + + AUTH_SERVICE_NOT_FIND_HANDLE(100211, "找不到执行器", "认证服务异常,请联系管理员"), + + ; + + private final int code; + private final String description; + private final String message; + + AuthErrorCodeEnum(int code, String description, String message){ + this.code = code; + this.description = description; + this.message = message; + } + + @Override + public int getCode() { + return this.code; + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public String getMessage() { + return this.message; + } +} + diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/errorcode/BaseAuthMsg.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/errorcode/BaseAuthMsg.java new file mode 100644 index 0000000..c8b8b32 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/errorcode/BaseAuthMsg.java @@ -0,0 +1,48 @@ +/** + * 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.plugins.security.exception.errorcode; + +/** + * 总消息类 用来存放消息 + * 将消息全部提取出至一个总文件 + * + * @author Parker + * @date 2020-09-22 17:07 + */ +public interface BaseAuthMsg { + + /** + * 获取消息的状态码 + * + * @return Integer + */ + int getCode(); + + /** + * 获取消息的状态码 + * + * @return Integer + */ + String getDescription(); + + /** + * 获取消息提示信息 + * + * @return String + */ + String getMessage(); + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AccessDeniedHandlerImpl.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AccessDeniedHandlerImpl.java new file mode 100644 index 0000000..c520dd9 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AccessDeniedHandlerImpl.java @@ -0,0 +1,49 @@ +/** + * 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.plugins.security.exception.handler; + +import cn.hutool.json.JSONUtil; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 权限不足 异常处理 + * + * @author Parker + * @date 2022年07月22日16:31:16 + */ +@Component +public class AccessDeniedHandlerImpl implements AccessDeniedHandler { + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { + accessDeniedException.printStackTrace(); + + // 权限不足 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_NO_ACCESS); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthEntryHandler.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthEntryHandler.java new file mode 100644 index 0000000..f095ad1 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthEntryHandler.java @@ -0,0 +1,42 @@ +/** + * 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.plugins.security.exception.handler; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opsli.plugins.security.exception.AuthException; + +/** + * 内部认证 服务异常处理 + * + * @author system + */ +public interface AuthEntryHandler { + + /** + * 处理 + * @param request request + * @param response response + * @param authException authException + * @throws IOException + * @throws ServletException + */ + void handle(HttpServletRequest request, HttpServletResponse response, AuthException authException) throws IOException, ServletException; + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthEntryHandlerImpl.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthEntryHandlerImpl.java new file mode 100644 index 0000000..085617b --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthEntryHandlerImpl.java @@ -0,0 +1,49 @@ +/** + * 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.plugins.security.exception.handler; + +import cn.hutool.json.JSONUtil; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 内部认证 异常处理 + * + * @author Parker + * @date 2022年07月22日16:31:16 + */ +@Component +public class AuthEntryHandlerImpl implements AuthEntryHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AuthException authException) throws IOException, ServletException { + Integer code = authException.getCode(); + String errorMessage = authException.getErrorMessage(); + + // 权限不足 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(code, errorMessage); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthenticationEntryPointImpl.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..1843a5d --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/exception/handler/AuthenticationEntryPointImpl.java @@ -0,0 +1,50 @@ +/** + * 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.plugins.security.exception.handler; + +import cn.hutool.json.JSONUtil; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 认证 异常处理 + * + * @author Parker + * @date 2022年07月22日16:31:16 + */ +@Component +public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint { + @Override + public void commence( + HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) + throws IOException, ServletException { + + // 认证失败请重新登录 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_AUTH_INVALID); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/AuthErrorHandler.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/AuthErrorHandler.java new file mode 100644 index 0000000..4cf68fd --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/AuthErrorHandler.java @@ -0,0 +1,65 @@ +/** + * 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.plugins.security.handler; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 认证异常 处理器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@Slf4j +@AllArgsConstructor +@Component +public class AuthErrorHandler implements LoginAccessDeniedListener { + + @Override + public boolean handle(Object loginModel, HttpServletRequest request, HttpServletResponse response, Exception e) { + if(!(e instanceof AuthException)){ + return true; + } + + AuthException ae = (AuthException) e; + + Integer code = ae.getCode(); + String description = ae.getDescription(); + String errorMessage = ae.getErrorMessage(); + + // 记录告警日志 + log.warn("认证服务异常(AuthException) => 异常编码:{} 描述:{} 异常:{}", + code, + description, + errorMessage); + + AuthResultWrapper customAuthResultWrapper = + AuthResultWrapper.getCustomResultWrapper(code, errorMessage); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customAuthResultWrapper)); + + return false; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/AuthServiceErrorHandler.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/AuthServiceErrorHandler.java new file mode 100644 index 0000000..a2f8510 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/AuthServiceErrorHandler.java @@ -0,0 +1,65 @@ +/** + * 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.plugins.security.handler; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 认证服务异常 处理器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@Slf4j +@AllArgsConstructor +@Component +public class AuthServiceErrorHandler implements LoginAccessDeniedListener { + + @Override + public boolean handle(Object loginModel, HttpServletRequest request, HttpServletResponse response, Exception e) { + if(!(e instanceof AuthServiceException)){ + return true; + } + + AuthServiceException ase = (AuthServiceException) e; + + Integer code = ase.getCode(); + String description = ase.getDescription(); + String errorMessage = ase.getErrorMessage(); + + // 记录告警日志 + log.warn("认证服务异常(AuthServiceException) => 异常编码:{} 描述:{} 异常:{}", + code, + description, + errorMessage); + + AuthResultWrapper customAuthResultWrapper = + AuthResultWrapper.getCustomResultWrapper(code, errorMessage); + + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customAuthResultWrapper)); + + return false; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginAccessDeniedListener.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginAccessDeniedListener.java new file mode 100644 index 0000000..019019d --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginAccessDeniedListener.java @@ -0,0 +1,49 @@ +/** + * 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.plugins.security.handler; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 登录后 监听器 + * + * @author Parker + * @date 2022-07-16 10:51 PM + **/ +public interface LoginAccessDeniedListener { + + /** + * 获得 监听器 类型 + * 注:如果指定了Type类型 则 如果当前消息类型与Listener的类型不符 则不会发器调用 + * @return Class + */ + default Class getModelType(){ + return Object.class; + } + + /** + * 执行 + * + * @param model 登录参数(认证信息) + * @param request request + * @param response response + * @param e 异常 + * @return boolean 决定是否继续执行异常监听器 + */ + boolean handle(Object model, HttpServletRequest request, HttpServletResponse response, Exception e); + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginAccessSuccessListener.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginAccessSuccessListener.java new file mode 100644 index 0000000..746039a --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginAccessSuccessListener.java @@ -0,0 +1,50 @@ +/** + * 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.plugins.security.handler; + +import org.springframework.security.core.Authentication; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 登录后 监听器 + * + * @author Parker + * @date 2022-07-16 10:51 PM + **/ +public interface LoginAccessSuccessListener { + + /** + * 获得 监听器 类型 + * 注:如果指定了Type类型 则 如果当前消息类型与Listener的类型不符 则不会发器调用 + * @return Class + */ + default Class getModelType(){ + return Object.class; + } + + /** + * 执行 + * + * @param model 登录参数(认证信息) + * @param authenticate 登录参数(认证信息) + * @param request request + * @param response response + */ + void handle(Object model, Authentication authenticate, HttpServletRequest request, HttpServletResponse response); + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginBeforeListener.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginBeforeListener.java new file mode 100644 index 0000000..fc6f9b8 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginBeforeListener.java @@ -0,0 +1,41 @@ +/** + * 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.plugins.security.handler; + +/** + * 登录前 监听器 + * + * @author Parker + * @date 2022-07-16 10:51 PM + **/ +public interface LoginBeforeListener { + + /** + * 获得 监听器 类型 + * 注:如果指定了Type类型 则 如果当前消息类型与Listener的类型不符 则不会发器调用 + * @return Class + */ + default Class getModelType(){ + return Object.class; + } + + /** + * 执行 + * @param model 登录参数(认证信息) + */ + void handle(Object model); + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginHandler.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginHandler.java new file mode 100644 index 0000000..856977f --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/LoginHandler.java @@ -0,0 +1,331 @@ +/** + * 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.plugins.security.handler; + +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; + +/** + * 登录策略执行器 + * + * @author Parker + * @date 2022-07-16 10:50 PM + **/ +public class LoginHandler { + + /** 是否初始化完成 */ + private boolean isInit; + + private AuthenticationManager authenticationManager; + private Class loginModelClass; + private List loginBeforeListenerList; + private List loginAccessSuccessListenerList; + private List loginAccessDeniedListenerList; + + public void login(T t, Function callback){ + if(!isInit || null == loginModelClass || null == authenticationManager){ + throw new RuntimeException("LoginHandler 未初始化"); + } + + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if(null == attributes){ + throw new RuntimeException("ServletRequest 未获取"); + } + HttpServletRequest request = attributes.getRequest(); + HttpServletResponse response = attributes.getResponse(); + + if(null == callback){ + AuthServiceException authException = new AuthServiceException(AuthErrorCodeEnum.AUTH_SERVICE_NOT_FIND_HANDLE); + // 执行登录失败 监听器 + this.fireFailureEvent(t, request, response, authException); + return; + } + + try { + // 执行登录前 监听器 + this.fireBeforeEvent(t); + + // 创建 Authentication + Authentication authenticate = authenticationManager + .authenticate(callback.apply(t)); + + // 执行登录成功 监听器 + this.fireSuccessEvent(t, authenticate, request, response); + }catch (Exception e){ + // 执行登录失败 监听器 + this.fireFailureEvent(t, request, response, e); + } + } + + + /** + * 登录前执行器 + * 用于登录前 通知一系列监听事件 + * @param t 登录参数 + */ + private void fireBeforeEvent(T t) { + if(null == loginBeforeListenerList){ + return; + } + for (LoginBeforeListener loginBeforeListener : loginBeforeListenerList) { + // 如果 类或接口相同或是超类或类接口 不同则直接跳出 + Class modelType = loginBeforeListener.getModelType(); + if(null == modelType + || (!Object.class.getName().equals(modelType.getName()) + && !t.getClass().getName().equals(modelType.getName())) ){ + continue; + } + + loginBeforeListener.handle(t); + } + } + + /** + * 登录成功后执行器 + * 用于登录后 通知一系列监听事件 + * @param t 登录参数 + */ + private void fireSuccessEvent( + T t, Authentication authenticate, HttpServletRequest request, HttpServletResponse response) { + if(null == loginAccessSuccessListenerList){ + return; + } + for (LoginAccessSuccessListener loginAccessSuccessListener : loginAccessSuccessListenerList) { + // 如果 类或接口相同或是超类或类接口 不同则直接跳出 + Class modelType = loginAccessSuccessListener.getModelType(); + if(null == modelType + || (!Object.class.getName().equals(modelType.getName()) + && !t.getClass().getName().equals(modelType.getName())) ){ + continue; + } + + loginAccessSuccessListener.handle(t, authenticate, request, response); + } + } + + /** + * 登录后执行器 + * 用于登录后 通知一系列监听事件 + * @param t 登录参数 + */ + private void fireFailureEvent( + T t, HttpServletRequest request, HttpServletResponse response, Exception e) { + if(null == loginAccessDeniedListenerList){ + return; + } + for (LoginAccessDeniedListener loginAccessDeniedListener : loginAccessDeniedListenerList) { + // 如果 类或接口相同或是超类或类接口 不同则直接跳出 + Class modelType = loginAccessDeniedListener.getModelType(); + if(null == modelType + || (!Object.class.getName().equals(modelType.getName()) + && !t.getClass().getName().equals(modelType.getName())) ){ + continue; + } + + boolean isNotBreak = loginAccessDeniedListener.handle(t, request, response, e); + if(!isNotBreak){ + break; + } + } + } + + + /** + * 登录执行器构建器 + * @param + */ + public static class Builder { + + private AuthenticationManager authenticationManager; + private Class loginModelClass; + private final BeforeListenerBuilder beforeListenerBuilder = + new BeforeListenerBuilder<>(this); + private final AccessSuccessListenerBuilder accessSuccessListenerBuilder = + new AccessSuccessListenerBuilder<>(this); + private final AccessDeniedListenerBuilder accessDeniedListenerBuilder = + new AccessDeniedListenerBuilder<>(this); + + /** + * 开始前监听器 + */ + public static class BeforeListenerBuilder { + + private final Builder builder; + + private final List listenerList = + new CopyOnWriteArrayList<>(); + + public BeforeListenerBuilder(Builder builder){ + this.builder = builder; + } + + /** + * 新增 认证前监听器 + * 注:如果指定了Type类型 则 如果当前消息类型与Listener的类型不符 则不会发器调用 + * @param loginBeforeListener 认证前监听器 + * @return Builder + */ + public BeforeListenerBuilder addListener( + LoginBeforeListener loginBeforeListener){ + listenerList.add(loginBeforeListener); + return this; + } + + public Builder and(){ + return builder; + } + } + + /** + * 成功后监听器 + */ + public static class AccessSuccessListenerBuilder { + + private final Builder builder; + private final List listenerList = + new CopyOnWriteArrayList<>(); + + public AccessSuccessListenerBuilder(Builder builder){ + this.builder = builder; + } + + /** + * 新增 认证成功监听器 + * 注:如果指定了Type类型 则 如果当前消息类型与Listener的类型不符 则不会发器调用 + * + * @param loginAccessSuccessListener 成功监听器 + * @return Builder + */ + public AccessSuccessListenerBuilder addListener( + LoginAccessSuccessListener loginAccessSuccessListener){ + listenerList.add(loginAccessSuccessListener); + return this; + } + + public Builder and(){ + return builder; + } + } + + /** + * 失败后监听器 + */ + public static class AccessDeniedListenerBuilder { + + private final Builder builder; + private final List listenerList = + new CopyOnWriteArrayList<>(); + + public AccessDeniedListenerBuilder(Builder builder){ + this.builder = builder; + } + + /** + * 新增 认证失败监听器 + * 注:如果指定了Type类型 则 如果当前消息类型与Listener的类型不符 则不会发器调用 + * + * @param loginAccessDeniedListener 失败监听器 + * @return Builder + */ + public AccessDeniedListenerBuilder addListener( + LoginAccessDeniedListener loginAccessDeniedListener){ + listenerList.add(loginAccessDeniedListener); + return this; + } + + public Builder and(){ + return builder; + } + } + + /** + * 初始化 登录模型 + * @param loginModelClass 登录模型Class + * @return Builder + */ + public Builder initLoginModelClass(Class loginModelClass){ + this.loginModelClass = loginModelClass; + return this; + } + + /** + * 初始化 认证控制器 + * @param authenticationManager 认证控制器 + * @return Builder + */ + public Builder initAuthenticationManager(AuthenticationManager authenticationManager){ + this.authenticationManager = authenticationManager; + return this; + } + + /** + * 认证开始前操作 + * + * @return BeforeListenerBuilder + */ + public BeforeListenerBuilder before(){ + return beforeListenerBuilder; + } + + /** + * 认证成功 操作 + * + * @return AccessSuccessListenerBuilder + */ + public AccessSuccessListenerBuilder accessSuccess(){ + return accessSuccessListenerBuilder; + } + + /** + * 认证失败 操作 + * + * @return AccessDeniedListenerBuilder + */ + public AccessDeniedListenerBuilder accessDenied(){ + return accessDeniedListenerBuilder; + } + + + /** + * 新增 认证失败监听器 + * @return LoginHandler + */ + public LoginHandler build(){ + LoginHandler loginHandler = new LoginHandler<>(); + + // 赋值 + loginHandler.isInit = true; + loginHandler.authenticationManager = this.authenticationManager; + loginHandler.loginModelClass = this.loginModelClass; + loginHandler.loginBeforeListenerList = this.beforeListenerBuilder.listenerList; + loginHandler.loginAccessSuccessListenerList = this.accessSuccessListenerBuilder.listenerList; + loginHandler.loginAccessDeniedListenerList = this.accessDeniedListenerBuilder.listenerList; + return loginHandler; + } + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/OtherErrorHandler.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/OtherErrorHandler.java new file mode 100644 index 0000000..3b3f772 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/OtherErrorHandler.java @@ -0,0 +1,51 @@ +/** + * 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.plugins.security.handler; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 其他异常 处理器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@Slf4j +@AllArgsConstructor +@Component +public class OtherErrorHandler implements LoginAccessDeniedListener { + + @Override + public boolean handle(Object loginModel, HttpServletRequest request, HttpServletResponse response, Exception e) { + // 记录异常日志 + log.error("认证其他未知异常 => 异常:{}", + e.getMessage(), + e); + + AuthResultWrapper customAuthResultWrapper = AuthResultWrapper.getErrorResultWrapper(); + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customAuthResultWrapper)); + + return false; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/SecurityErrorHandler.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/SecurityErrorHandler.java new file mode 100644 index 0000000..ef22b06 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/handler/SecurityErrorHandler.java @@ -0,0 +1,77 @@ +/** + * 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.plugins.security.handler; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.utils.WebUtils; +import org.opsli.plugins.security.vo.AuthResultWrapper; +import org.springframework.security.authentication.*; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Security认证异常 处理器 + * @author Parker + * @date 2022-07-17 12:57 PM + **/ +@Slf4j +@AllArgsConstructor +@Component +public class SecurityErrorHandler implements LoginAccessDeniedListener { + + @Override + public boolean handle(Object loginModel, HttpServletRequest request, HttpServletResponse response, Exception e) { + if(e instanceof BadCredentialsException){ + // 凭证不正确 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_WRONG_PASSWORD); + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + return false; + }else if(e instanceof LockedException){ + // 账号锁定 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_ACCOUNT_LOCKED); + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + return false; + }else if(e instanceof DisabledException){ + // 账号未启用 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_ACCOUNT_DISABLED); + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + return false; + }else if(e instanceof AccountExpiredException){ + // 账号过期 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_ACCOUNT_EXPIRED); + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + return false; + }else if(e instanceof CredentialsExpiredException){ + // 凭证过期 + AuthResultWrapper customResultWrapper = + AuthResultWrapper.getCustomResultWrapper(AuthErrorCodeEnum.AUTH_ACCOUNT_CREDENTIALS_EXPIRED); + WebUtils.renderString(request, response, JSONUtil.toJsonStr(customResultWrapper)); + return false; + } + + return true; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/properties/AuthProperties.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/properties/AuthProperties.java new file mode 100644 index 0000000..8e91c93 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/properties/AuthProperties.java @@ -0,0 +1,55 @@ +/** + * 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.plugins.security.properties; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 认证配置 + * + * @author Parker + * @date 2020-09-15 + */ +@Component +@ConfigurationProperties(prefix = AuthProperties.PROP_PREFIX) +@Data +@EqualsAndHashCode(callSuper = false) +public class AuthProperties { + + public static final String PROP_PREFIX = "opsli.auth"; + + /** 排除URL */ + private UrlExclusion urlExclusion; + + /** 凭证过期时间 -1 为不处理 */ + private int credentialsExpired = -1; + + @Data + public static class UrlExclusion { + + /** 未登陆状态下可以访问 */ + private List anonymous; + + /** 无限制 */ + private List permitAll; + + } +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/EmailCodeAuthenticationProvider.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/EmailCodeAuthenticationProvider.java new file mode 100644 index 0000000..c45953e --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/EmailCodeAuthenticationProvider.java @@ -0,0 +1,79 @@ +/** + * 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.plugins.security.provider; + +import lombok.AllArgsConstructor; +import org.opsli.plugins.security.authentication.EmailCodeAuthenticationToken; +import org.opsli.plugins.security.checker.DefaultPreAuthenticationChecks; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.service.LoadUserDetailServiceFactory; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +/** + * 邮件+验证码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +@AllArgsConstructor +@Component +public class EmailCodeAuthenticationProvider implements AuthenticationProvider,IAuthenticationProvider { + + private final LoadUserDetailServiceFactory loadUserDetailServiceFactory; + private final DefaultPreAuthenticationChecks defaultPreAuthenticationChecks; + + @Override + public Class getAuthenticationTokenClass() { + return EmailCodeAuthenticationToken.class; + } + + /** + * 指定所代理的 authenticationToken 类 + * 注:很重要要不然不生效 + */ + @Override + public boolean supports(Class authentication) { + return this.getAuthenticationTokenClass().isAssignableFrom(authentication); + } + + @Override + public Authentication authenticate(Authentication unAuthenticationToken) throws AuthenticationException { + ILoadUserDetailService loadUserDetailService = + loadUserDetailServiceFactory.getUserDetailService(this.getAuthenticationTokenClass()) + // ERROR => 未加载到 用户服务 + .orElseThrow(() -> new AuthServiceException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER_SERVICE)); + + + // 此时的authentication还没认证,获取邮箱号码 + UserDetails user = + loadUserDetailService.loadUserByPrincipal(unAuthenticationToken.getPrincipal()) + // ERROR => 未获取到用户 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER)); + + // 检查其他信息 + defaultPreAuthenticationChecks.check(user); + + return createSuccessAuthentication(unAuthenticationToken, user); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/EmailPasswordAuthenticationProvider.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/EmailPasswordAuthenticationProvider.java new file mode 100644 index 0000000..0a04645 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/EmailPasswordAuthenticationProvider.java @@ -0,0 +1,107 @@ +/** + * 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.plugins.security.provider; + +import lombok.AllArgsConstructor; +import org.opsli.plugins.security.authentication.EmailPasswordAuthenticationToken; +import org.opsli.plugins.security.checker.DefaultPostAuthenticationChecks; +import org.opsli.plugins.security.checker.DefaultPreAuthenticationChecks; +import org.opsli.plugins.security.eventbus.SpringSecurityEventBus; +import org.opsli.plugins.security.eventdto.BadCredentials; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.service.LoadUserDetailServiceFactory; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + + +/** + * 邮箱+密码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +@AllArgsConstructor +@Component +public class EmailPasswordAuthenticationProvider implements AuthenticationProvider,IAuthenticationProvider { + + private final LoadUserDetailServiceFactory loadUserDetailServiceFactory; + private final DefaultPreAuthenticationChecks defaultPreAuthenticationChecks; + private final DefaultPostAuthenticationChecks defaultPostAuthenticationChecks; + private final PasswordEncoder passwordEncoder; + private final SpringSecurityEventBus springSecurityEventBus; + + + @Override + public Class getAuthenticationTokenClass() { + return EmailPasswordAuthenticationToken.class; + } + + /** + * 指定所代理的 authenticationToken 类 + * 注:很重要要不然不生效 + */ + @Override + public boolean supports(Class authentication) { + return this.getAuthenticationTokenClass().isAssignableFrom(authentication); + } + + @Override + public Authentication authenticate(Authentication unAuthenticationToken) throws AuthenticationException { + ILoadUserDetailService loadUserDetailService = + loadUserDetailServiceFactory.getUserDetailService(this.getAuthenticationTokenClass()) + // ERROR => 未加载到 用户服务 + .orElseThrow(() -> new AuthServiceException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER_SERVICE)); + + // 原始密码 + String rawPassword = (String) unAuthenticationToken.getCredentials(); + + // 此时的authentication还没认证,获取邮箱号码 + UserDetails user = + loadUserDetailService.loadUserByPrincipal(unAuthenticationToken.getPrincipal()) + // ERROR => 未获取到用户 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER)); + + // 校验密码是否正确 + boolean check = PasswordUtil.matches(passwordEncoder, rawPassword, user.getPassword()); + if(!check){ + // 发生 EventBus + BadCredentials badCredentials = BadCredentials.builder() + .principal((String) unAuthenticationToken.getPrincipal()) + .credentials(rawPassword) + .build(); + springSecurityEventBus.post(badCredentials); + + // ERROR => 密码不正确 + throw new BadCredentialsException(AuthErrorCodeEnum.AUTH_WRONG_PASSWORD.getMessage()); + } + + // 检查其他信息 + defaultPreAuthenticationChecks.check(user); + defaultPostAuthenticationChecks.check(user); + + return createSuccessAuthentication(unAuthenticationToken, user); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/IAuthenticationProvider.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/IAuthenticationProvider.java new file mode 100644 index 0000000..d2711af --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/IAuthenticationProvider.java @@ -0,0 +1,50 @@ +/** + * 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.plugins.security.provider; + +import org.opsli.plugins.security.authentication.AfterAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; + +/** + * 认证授权器 + * + * @author Parker + * @date 2022-07-18 11:18 AM + **/ +public interface IAuthenticationProvider { + + /** + * 获得授权TokenClass + * @return Class + */ + Class getAuthenticationTokenClass(); + + /** + * 创建认证成功授权 + * @param unAuthenticationToken 授权前 AuthenticationToken + * @param user 用户信息 + * @return Authentication + */ + default Authentication createSuccessAuthentication(Authentication unAuthenticationToken, UserDetails user) { + AfterAuthenticationToken result = + new AfterAuthenticationToken(user, + unAuthenticationToken.getCredentials(), user.getAuthorities()); + result.setDetails(unAuthenticationToken.getDetails()); + return result; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/MobileCodeAuthenticationProvider.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/MobileCodeAuthenticationProvider.java new file mode 100644 index 0000000..15f846c --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/MobileCodeAuthenticationProvider.java @@ -0,0 +1,79 @@ +/** + * 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.plugins.security.provider; + +import lombok.AllArgsConstructor; +import org.opsli.plugins.security.authentication.MobileCodeAuthenticationToken; +import org.opsli.plugins.security.checker.DefaultPreAuthenticationChecks; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.service.LoadUserDetailServiceFactory; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +/** + * 手机+验证码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +@AllArgsConstructor +@Component +public class MobileCodeAuthenticationProvider implements AuthenticationProvider,IAuthenticationProvider { + + private final LoadUserDetailServiceFactory loadUserDetailServiceFactory; + private final DefaultPreAuthenticationChecks defaultPreAuthenticationChecks; + + @Override + public Class getAuthenticationTokenClass() { + return MobileCodeAuthenticationToken.class; + } + + /** + * 指定所代理的 authenticationToken 类 + * 注:很重要要不然不生效 + */ + @Override + public boolean supports(Class authentication) { + return this.getAuthenticationTokenClass().isAssignableFrom(authentication); + } + + @Override + public Authentication authenticate(Authentication unAuthenticationToken) throws AuthenticationException { + ILoadUserDetailService loadUserDetailService = + loadUserDetailServiceFactory.getUserDetailService(this.getAuthenticationTokenClass()) + // ERROR => 未加载到 用户服务 + .orElseThrow(() -> new AuthServiceException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER_SERVICE)); + + + // 此时的authentication还没认证,获取邮箱号码 + UserDetails user = + loadUserDetailService.loadUserByPrincipal(unAuthenticationToken.getPrincipal()) + // ERROR => 未获取到用户 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER)); + + // 检查其他信息 + defaultPreAuthenticationChecks.check(user); + + return createSuccessAuthentication(unAuthenticationToken, user); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/MobilePasswordAuthenticationProvider.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/MobilePasswordAuthenticationProvider.java new file mode 100644 index 0000000..1667dc1 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/MobilePasswordAuthenticationProvider.java @@ -0,0 +1,106 @@ +/** + * 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.plugins.security.provider; + +import lombok.AllArgsConstructor; +import org.opsli.plugins.security.authentication.MobilePasswordAuthenticationToken; +import org.opsli.plugins.security.checker.DefaultPostAuthenticationChecks; +import org.opsli.plugins.security.checker.DefaultPreAuthenticationChecks; +import org.opsli.plugins.security.eventbus.SpringSecurityEventBus; +import org.opsli.plugins.security.eventdto.BadCredentials; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.service.LoadUserDetailServiceFactory; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +/** + * 手机+密码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +@AllArgsConstructor +@Component +public class MobilePasswordAuthenticationProvider implements AuthenticationProvider,IAuthenticationProvider { + + private final LoadUserDetailServiceFactory loadUserDetailServiceFactory; + private final DefaultPreAuthenticationChecks defaultPreAuthenticationChecks; + private final DefaultPostAuthenticationChecks defaultPostAuthenticationChecks; + private final PasswordEncoder passwordEncoder; + private final SpringSecurityEventBus springSecurityEventBus; + + + @Override + public Class getAuthenticationTokenClass() { + return MobilePasswordAuthenticationToken.class; + } + + /** + * 指定所代理的 authenticationToken 类 + * 注:很重要要不然不生效 + */ + @Override + public boolean supports(Class authentication) { + return this.getAuthenticationTokenClass().isAssignableFrom(authentication); + } + + @Override + public Authentication authenticate(Authentication unAuthenticationToken) throws AuthenticationException { + ILoadUserDetailService loadUserDetailService = + loadUserDetailServiceFactory.getUserDetailService(this.getAuthenticationTokenClass()) + // ERROR => 未加载到 用户服务 + .orElseThrow(() -> new AuthServiceException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER_SERVICE)); + + // 原始密码 + String rawPassword = (String) unAuthenticationToken.getCredentials(); + + // 此时的authentication还没认证,获取邮箱号码 + UserDetails user = + loadUserDetailService.loadUserByPrincipal(unAuthenticationToken.getPrincipal()) + // ERROR => 未获取到用户 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER)); + + // 校验密码是否正确 + boolean check = PasswordUtil.matches(passwordEncoder, rawPassword, user.getPassword()); + if(!check){ + // 发生 EventBus + BadCredentials badCredentials = BadCredentials.builder() + .principal((String) unAuthenticationToken.getPrincipal()) + .credentials(rawPassword) + .build(); + springSecurityEventBus.post(badCredentials); + + // ERROR => 密码不正确 + throw new BadCredentialsException(AuthErrorCodeEnum.AUTH_WRONG_PASSWORD.getMessage()); + } + + // 检查其他信息 + defaultPreAuthenticationChecks.check(user); + defaultPostAuthenticationChecks.check(user); + + return createSuccessAuthentication(unAuthenticationToken, user); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/UsernamePasswordAuthenticationProvider.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/UsernamePasswordAuthenticationProvider.java new file mode 100644 index 0000000..4afb26c --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/provider/UsernamePasswordAuthenticationProvider.java @@ -0,0 +1,105 @@ +/** + * 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.plugins.security.provider; + +import lombok.AllArgsConstructor; +import org.opsli.plugins.security.checker.DefaultPostAuthenticationChecks; +import org.opsli.plugins.security.checker.DefaultPreAuthenticationChecks; +import org.opsli.plugins.security.eventbus.SpringSecurityEventBus; +import org.opsli.plugins.security.eventdto.BadCredentials; +import org.opsli.plugins.security.exception.AuthException; +import org.opsli.plugins.security.exception.AuthServiceException; +import org.opsli.plugins.security.exception.errorcode.AuthErrorCodeEnum; +import org.opsli.plugins.security.service.ILoadUserDetailService; +import org.opsli.plugins.security.service.LoadUserDetailServiceFactory; +import org.opsli.plugins.security.utils.PasswordUtil; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +/** + * 用户名+密码 验证器 + * + * @author Parker + * @date 2022年07月18日10:41:50 + */ +@AllArgsConstructor +@Component +public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider,IAuthenticationProvider { + + private final LoadUserDetailServiceFactory loadUserDetailServiceFactory; + private final DefaultPreAuthenticationChecks defaultPreAuthenticationChecks; + private final DefaultPostAuthenticationChecks defaultPostAuthenticationChecks; + private final PasswordEncoder passwordEncoder; + private final SpringSecurityEventBus springSecurityEventBus; + + @Override + public Class getAuthenticationTokenClass() { + return UsernamePasswordAuthenticationToken.class; + } + + /** + * 指定所代理的 authenticationToken 类 + * 注:很重要要不然不生效 + */ + @Override + public boolean supports(Class authentication) { + return this.getAuthenticationTokenClass().isAssignableFrom(authentication); + } + + @Override + public Authentication authenticate(Authentication unAuthenticationToken) throws AuthenticationException { + ILoadUserDetailService loadUserDetailService = + loadUserDetailServiceFactory.getUserDetailService(this.getAuthenticationTokenClass()) + // ERROR => 未加载到 用户服务 + .orElseThrow(() -> new AuthServiceException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER_SERVICE)); + + // 原始密码 + String rawPassword = (String) unAuthenticationToken.getCredentials(); + + // 此时的authentication还没认证,获取邮箱号码 + UserDetails user = + loadUserDetailService.loadUserByPrincipal(unAuthenticationToken.getPrincipal()) + // ERROR => 未获取到用户 + .orElseThrow(() -> new AuthException(AuthErrorCodeEnum.AUTH_NOT_FIND_USER)); + + // 校验密码是否正确 + boolean check = PasswordUtil.matches(passwordEncoder, rawPassword, user.getPassword()); + if(!check){ + // 发生 EventBus + BadCredentials badCredentials = BadCredentials.builder() + .principal((String) unAuthenticationToken.getPrincipal()) + .credentials(rawPassword) + .build(); + springSecurityEventBus.post(badCredentials); + + // ERROR => 密码不正确 + throw new BadCredentialsException(AuthErrorCodeEnum.AUTH_WRONG_PASSWORD.getMessage()); + } + + // 检查其他信息 + defaultPreAuthenticationChecks.check(user); + defaultPostAuthenticationChecks.check(user); + + return createSuccessAuthentication(unAuthenticationToken, user); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/service/ILoadUserDetailService.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/service/ILoadUserDetailService.java new file mode 100644 index 0000000..05247fb --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/service/ILoadUserDetailService.java @@ -0,0 +1,53 @@ +/** + * 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.plugins.security.service; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.Optional; + +/** + * 加载用户信息 + * + * @author Parker + * @date 2022-07-16 3:44 PM + **/ +public interface ILoadUserDetailService { + + /** + * 获得Class 类型 + * 该方法 标识该Service 能够支持 哪儿些 AuthenticationToken + * 注:重复的 AuthenticationToken.class 会被覆盖 + * @return Class + */ + Collection> getClassTypes(); + + /** + * 加载用户信息 + * 实现方式: 只需要负责 三步处理 + * 1. 如何获得用户? + * 2. 如果用户为空怎么办? + * 3. 如何将系统的用户属性封装成 UserDetails 返回出去? + * (推荐使用 UserDetailModel.builder()来完成此操作 ) + * + * @param principal 主键 + * @return Optional + */ + Optional loadUserByPrincipal(Object principal); + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/service/LoadUserDetailServiceFactory.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/service/LoadUserDetailServiceFactory.java new file mode 100644 index 0000000..52c3ae8 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/service/LoadUserDetailServiceFactory.java @@ -0,0 +1,79 @@ +/** + * 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.plugins.security.service; + +import cn.hutool.core.collection.CollUtil; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 加载用户信息工厂 + * + * @author Parker + * @date 2022-07-18 10:16 AM + **/ +@Component +public class LoadUserDetailServiceFactory { + + private boolean isInit; + + private final Map, ILoadUserDetailService> + serviceMap = new ConcurrentHashMap<>(); + + @Autowired + private ListableBeanFactory listableBeanFactory; + + /** + * 获得 加载用户服务 + * @param clazz Token class + * @return Optional + */ + public Optional getUserDetailService(Class clazz){ + if(!isInit){ + throw new RuntimeException("加载用户工厂未初始化"); + } + + return Optional.ofNullable(serviceMap.get(clazz)); + } + + + @PostConstruct + public void init(){ + Map iLoadUserDetailServiceMap = + listableBeanFactory.getBeansOfType(ILoadUserDetailService.class); + for (Map.Entry serviceEntry : iLoadUserDetailServiceMap.entrySet()) { + ILoadUserDetailService loadUserDetailService = serviceEntry.getValue(); + + // 根据classType 循环加载 Service + Collection> classTypes = loadUserDetailService.getClassTypes(); + if(CollUtil.isEmpty(classTypes)){ + continue; + } + + classTypes.forEach((classType)-> serviceMap.put(classType, loadUserDetailService)); + } + isInit = true; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/IpaddrUtil.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/IpaddrUtil.java new file mode 100644 index 0000000..7acc4f7 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/IpaddrUtil.java @@ -0,0 +1,114 @@ +/** + * 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.plugins.security.utils; + +import cn.hutool.core.lang.Validator; +import cn.hutool.core.net.NetUtil; +import cn.hutool.core.util.StrUtil; + +import javax.servlet.http.HttpServletRequest; + +/** + * IP 工具类 + * + * @author Parker + * @date 2020-09-19 23:21 + */ +public final class IpaddrUtil { + + /** 排除结果 */ + private static final String UNKNOWN = "unknown"; + /** 尝试字段 */ + private static final String[] HEADERS_TO_TRY = { + "X-Forwarded-For", + "Proxy-Client-IP", + "WL-Proxy-Client-IP", + "HTTP_X_FORWARDED_FOR", + "HTTP_X_FORWARDED", + "HTTP_X_CLUSTER_CLIENT_IP", + "HTTP_CLIENT_IP", + "HTTP_FORWARDED_FOR", + "HTTP_FORWARDED", + "HTTP_VIA", + "REMOTE_ADDR", + "X-Real-IP" + }; + + + /*** + * 获取客户端地址 + * + * @param request request + * @return String + */ + public static String getClientAddress(HttpServletRequest request) { + for (String header : HEADERS_TO_TRY) { + String address = request.getHeader(header); + if (StrUtil.isNotBlank(address) + && !UNKNOWN.equalsIgnoreCase(address)) { + return address; + } + } + return request.getRemoteAddr(); + } + + /*** + * 获取客户端地址 (多重代理只获得第一个) + * + * @param request request + * @return String + */ + public static String getClientAddressBySingle(HttpServletRequest request) { + String clientAddress = getClientAddress(request); + return NetUtil.getMultistageReverseProxyIp(clientAddress); + } + + /*** + * 获取客户端IP + * + * @param request request + * @return String + */ + public static String getClientId(HttpServletRequest request) { + for (String header : HEADERS_TO_TRY) { + String ip = request.getHeader(header); + if (StrUtil.isNotBlank(ip) && !UNKNOWN.equalsIgnoreCase(ip)) { + String reverseProxyIp = NetUtil.getMultistageReverseProxyIp(ip); + if(Validator.isIpv4(reverseProxyIp) || Validator.isIpv6(reverseProxyIp)){ + // 判断是否为IP 返回原始IP + return ip; + } + } + } + // 否则返回 空地址 + return ""; + } + + /*** + * 获取客户端IP (多重代理只获得第一个) + * + * @param request request + * @return String + */ + public static String getClientIdBySingle(HttpServletRequest request) { + String clientIp = getClientId(request); + return NetUtil.getMultistageReverseProxyIp(clientIp); + } + + // =============== + + private IpaddrUtil(){} +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/JWTUtil.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/JWTUtil.java new file mode 100644 index 0000000..68c5f61 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/JWTUtil.java @@ -0,0 +1,298 @@ +/** + * 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.plugins.security.utils; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.exceptions.ValidateException; +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTPayload; +import cn.hutool.jwt.JWTValidator; +import cn.hutool.jwt.signers.JWTSigner; +import cn.hutool.jwt.signers.JWTSignerUtil; +import org.opsli.plugins.security.JwtConstants; +import org.opsli.plugins.security.LoginUserInfo; + +import java.util.Date; +import java.util.Map; + +/** + * JWT 的工具类:包含了创建和解码的工具 + * + * @author Parker + * @date 2021年12月22日20:01:23 + */ +public final class JWTUtil { + + /** + * 刷新 Token + * + * @param userInfo 用户信息 + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + public static String generateRefreshToken(LoginUserInfo userInfo, String secret, Integer expireMinutes) { + Map payloadsMap = BeanUtil.beanToMap(userInfo); + payloadsMap.put(JwtConstants.JWT_CLAIM_TAG, Tag.REFRESH_TOKEN.getTag()); + + // 生成新Token + return generate(payloadsMap, secret, expireMinutes); + } + + /** + * 认证 Token + * + * @param refreshToken 刷新Token + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + public static String generateAuthToken(String refreshToken, String secret, Integer expireMinutes) { + // 验证 刷新Token 是否失效 + verify(refreshToken, secret); + + // 获得 载荷数据 + LoginUserInfo loginUserFromToken = getLoginUserFromToken(refreshToken); + Map payloadsMap = BeanUtil.beanToMap(loginUserFromToken); + payloadsMap.put(JwtConstants.JWT_CLAIM_TAG, Tag.TOKEN.getTag()); + + // 生成新Token + return generate(payloadsMap, secret, expireMinutes); + } + + /** + * 认证 Token + * + * @param userInfo 用户信息 + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + public static String generateAuthToken(LoginUserInfo userInfo, String secret, Integer expireMinutes) { + Map payloadsMap = BeanUtil.beanToMap(userInfo); + payloadsMap.put(JwtConstants.JWT_CLAIM_TAG, Tag.TOKEN.getTag()); + + // 生成新Token + return generate(payloadsMap, secret, expireMinutes); + } + + + /** + * 生成Token + * + * @param payloadsMap 载荷数据 + * @param secret 盐 + * @param expireMinutes 过期时间,单位分钟 + * @return String + */ + private static String generate(Map payloadsMap, String secret, Integer expireMinutes) { + byte[] keys = Base64.encode(secret).getBytes(); + JWTSigner jwtSigner = JWTSignerUtil.hs256(keys); + + // 签发时间 + Date issuedAt = DateUtil.date(); + + return JWT.create() + // 载荷数据 + .addPayloads(payloadsMap) + // 签发时间 + .setIssuedAt(DateUtil.offsetMinute(issuedAt, JwtConstants.JWT_SIGNATURE_DELAY)) + // 过期时间 + .setExpiresAt(DateUtil.offsetMinute(issuedAt, expireMinutes)) + // 签名 + .sign(jwtSigner); + } + + + /** + * 校验Token 是否正确 + * + * @param token Token + * @param secret 盐 + */ + public static void verify(String token, String secret) { + byte[] keys = Base64.encode(secret).getBytes(); + JWTSigner jwtSigner = JWTSignerUtil.hs256(keys); + + JWTValidator validator = JWTValidator.of(token); + try { + // 验证签名 + validator.validateAlgorithm(jwtSigner); + } catch (Exception e) { + throw new ValidateException(100524, "Token无效,请重新登录"); + } + + try { + // 验证时间 + validator.validateDate(); + } catch (Exception e) { + throw new ValidateException(100525, "Token已过期,请重新登录", e); + } + } + + /** + * 获得登陆用户信息 + * + * @param token Token + */ + public static LoginUserInfo getLoginUserFromToken(String token) { + JSONObject payloads = JWT.of(token) + .getPayloads(); + // 移除标识 + payloads.remove(JwtConstants.JWT_CLAIM_TAG); + return payloads.toBean(LoginUserInfo.class); + } + + /** + * 获得登陆用户信息 字符串 + * + * @param token Token + */ + public static String getLoginUserStrFromToken(String token) { + JSONObject payloads = JWT.of(token) + .getPayloads(); + // 移除标识 + payloads.remove(JwtConstants.JWT_CLAIM_TAG); + return payloads.toString(); + } + + /** + * 获得Token的签名时间 + * + * @param token Token + */ + public static Date getIssuedDateFromToken(String token) { + // 获得失效时间 + return JWT.of(token).getPayload() + .getClaimsJson().getDate(JWTPayload.ISSUED_AT); + } + + /** + * 获得Token的失效时间 + * + * @param token Token + */ + public static Date getExpiredDateFromToken(String token) { + // 获得失效时间 + return JWT.of(token).getPayload() + .getClaimsJson().getDate(JWTPayload.EXPIRES_AT); + } + + /** + * 判断是否是刷新Token + * + * @param token Token + */ + public static boolean isRefreshToken(String token) { + String tag = Tag.TOKEN.getTag(); + try { + tag = JWT.of(token).getPayload() + .getClaimsJson().getStr(JwtConstants.JWT_CLAIM_TAG); + } catch (Exception ignored) { + } + return Tag.REFRESH_TOKEN.getTag().equals(tag); + } + + /** + * 标签 + */ + private enum Tag { + + /** + * 刷新Token + */ + REFRESH_TOKEN("0"), + /** + * 认证Token + */ + TOKEN("1"); + + private final String tag; + + Tag(String tag) { + this.tag = tag; + } + + public String getTag() { + return tag; + } + } + + + /** + * 私有化构造函数 + */ + private JWTUtil() {} + + + public static void main(String[] args) { + String secret = "8128212"; + + LoginUserInfo loginUserInfo = new LoginUserInfo(); + loginUserInfo.setLoginIp("127.0.0.1"); + loginUserInfo.setMobile("18888888888"); + loginUserInfo.setEmail("meet.parker@foxmail.com"); + loginUserInfo.setUsername("u_111111"); + loginUserInfo.setNickname("Parker"); + loginUserInfo.setUid("12321321L"); + + // 刷新Token 一个月失效 + String refreshToken = JWTUtil.generateRefreshToken(loginUserInfo, secret, 43200); + // 认证Token 两小时失效 + String fastToken = JWTUtil.generateAuthToken(refreshToken, secret, 120); + // 认证Token 十年失效 + String slowToken = JWTUtil.generateAuthToken(refreshToken, secret, 5256000); +// for (int i = 0; i < 100; i++) { +// long l = System.currentTimeMillis(); +// token = JwtUtil.generate(loginUserInfo, secret, 3); +// System.out.println("普通Token耗时:" + (System.currentTimeMillis() - l)); +// } + + System.out.println("刷新Token 一个月失效"); + System.out.println(JwtConstants.TOKEN_HEAD + refreshToken); + System.out.println(""); + System.out.println("认证Token 两小时失效"); + System.out.println(JwtConstants.TOKEN_HEAD + fastToken); + System.out.println(""); + System.out.println("认证Token 十年失效"); + System.out.println(JwtConstants.TOKEN_HEAD + slowToken); + System.out.println(""); + + + LoginUserInfo loginUserByToken = JWTUtil.getLoginUserFromToken(refreshToken); + System.out.println(JSONUtil.toJsonStr(loginUserByToken)); + + Date date = JWTUtil.getExpiredDateFromToken(refreshToken); + System.out.println(DateUtil.formatDateTime(date)); + + // 刷新Token +// for (int i = 0; i < 100; i++) { +// long l = System.currentTimeMillis(); +// token = JWTUtil.refresh(refreshToken, secret, 3); +// System.out.println("刷新Token耗时:" + (System.currentTimeMillis() - l)); +// } + + + ThreadUtil.sleep(2000); + JWTUtil.verify(refreshToken, secret); + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/PasswordUtil.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/PasswordUtil.java new file mode 100644 index 0000000..206ffc0 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/PasswordUtil.java @@ -0,0 +1,122 @@ +/** + * 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.plugins.security.utils; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * 密码工具类 + * + * @author Parker + * @date 2022-07-19 10:21 AM + **/ +public final class PasswordUtil { + + private static final String PREFIX = "TS{"; + private static final String SUFFIX = "}"; + + /** + * 加密密码 + * + * @param passwordEncoder encoder + * @param rawPassword 原始密码 + * @return String + */ + public static String encode(PasswordEncoder passwordEncoder, String rawPassword){ + long timeMillis = System.currentTimeMillis(); + + StringBuilder sb = new StringBuilder(); + sb.append(PREFIX).append(Base64.encode(String.valueOf(timeMillis))).append(SUFFIX) + .append(passwordEncoder.encode(rawPassword)); + return sb.toString(); + } + + /** + * 验证密码是否正确 + * + * @param passwordEncoder encoder + * @param rawPassword 原始密码 + * @param encodedPassword 加密密码 + * @return String + */ + public static boolean matches( + PasswordEncoder passwordEncoder, String rawPassword, String encodedPassword){ + + // 获得原始密码 + String timeMillisStr = StrUtil.subBetween(encodedPassword, PREFIX, SUFFIX); + String replaceEncodedPassword = + encodedPassword.replace(PREFIX + timeMillisStr + SUFFIX, ""); + + // 判断密码是否正确 + return passwordEncoder.matches(rawPassword, replaceEncodedPassword); + } + + /** + * 判断凭证是否过期 + * + * @param credentials 原始密码 + * @param expiredDayCount 过期天数 + * @return String + */ + public static boolean isCredentialsNonExpired(String credentials, int expiredDayCount){ + // 如果小于0 默认为不处理 + if(expiredDayCount < 0){ + return true; + } + + // 获得原始密码 + String timeMillisStr = Base64.decodeStr( + StrUtil.subBetween(credentials, PREFIX, SUFFIX)); + + // 当前时间 + DateTime currDate = DateUtil.date(); + + // 创建时间 + DateTime createDate = DateUtil.date(Long.parseLong(timeMillisStr)); + + // 过期时间 + DateTime expiredDate = DateUtil.offsetDay( + DateUtil.date(Long.parseLong(timeMillisStr)), expiredDayCount); + + // 如果 创建时间 大于 当前时间 || 过期时间 大于 当前时间 都判定凭证失效 + return DateUtil.compare(createDate, currDate) <= 0 && + DateUtil.compare(expiredDate, currDate) >= 0; + } + + //private + + public static void main(String[] args) { + PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + String rawPassword = "Aa123456."; + + String encode = encode(passwordEncoder, rawPassword); + System.out.println(encode); + + boolean isTrue = matches(passwordEncoder, rawPassword, encode); + System.out.println(isTrue); + + boolean isNonExpired = isCredentialsNonExpired(encode, 1); + System.out.println(isNonExpired); + } + + private PasswordUtil(){} +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/WebUtils.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/WebUtils.java new file mode 100644 index 0000000..49d159f --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/utils/WebUtils.java @@ -0,0 +1,74 @@ +/** + * 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.plugins.security.utils; + + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * response 返回 + * + * @author Parker + * @date 2022年07月15日14:04:13 + */ +public class WebUtils { + + /** + * 将字符串渲染到客户端 + * + * @param response 渲染对象 + * @param string 待渲染的字符串 + * @return null + */ + public static String renderString(HttpServletRequest request, HttpServletResponse response, String string) { + try{ + response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); + response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); + response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); + response.setContentType("application/json; charset=utf-8"); + + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + response.getWriter().flush(); + } + catch (IOException e){ + e.printStackTrace(); + } + return null; + } + + /** + * 返回异常值 + * + * @param msg 消息 + */ + public static void renderErrorByAlert(HttpServletResponse response, String msg){ + try { + response.setCharacterEncoding("utf-8"); + response.setContentType("text/html;charset=utf-8;"); + response.getWriter().write( + ""); + response.getWriter().flush(); + }catch (Exception e){ + e.printStackTrace(); + } + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/vo/AuthResultWrapper.java b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/vo/AuthResultWrapper.java new file mode 100644 index 0000000..87659a1 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/java/org/opsli/plugins/security/vo/AuthResultWrapper.java @@ -0,0 +1,301 @@ +/** + * 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.plugins.security.vo; + +import lombok.*; +import lombok.experimental.Accessors; +import org.opsli.plugins.security.exception.errorcode.BaseAuthMsg; + +import java.io.Serializable; + +/** + * 返回包装类 + * + * @author Parker + * @date 2021年12月30日15:31:41 + */ +@Data +@Builder +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +public class AuthResultWrapper implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 响应提示信息 + */ + private String msg; + + /** + * 返回码:0正常,-1以上为错误信息 + */ + private int code; + + /** + * 返回 + */ + private T data; + + /** + * 时间戳 + */ + private long timestamp; + + + /** + * 获取默认的成功信息, + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getSuccessResultWrapperByMsg(String msg) { + return AuthResultWrapper.builder() + .code(StateCodeEnum.SUCCESS.getCode()) + .msg(msg) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取默认的成功信息, + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getSuccessResultWrapper() { + return getSuccessResultWrapper(null); + } + + /** + * 获取默认的成功信息, + * 默认的成功状态码 自定义code码 + * @param data 数据 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getBackSuccessResultWrapper(T data) { + return AuthResultWrapper.builder() + .code(BackStateEnum.SUCCESS.getCode()) + .msg(BackStateEnum.SUCCESS.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取默认的成功信息, + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param data 数据 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getSuccessResultWrapper(T data) { + return AuthResultWrapper.builder() + .code(StateCodeEnum.SUCCESS.getCode()) + .msg(StateCodeEnum.SUCCESS.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取默认的错误的信息 + * 默认的失败状态码 {@link StateCodeEnum#ERROR} + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getErrorResultWrapper() { + return getErrorResultWrapper(null); + } + + /** + * 获取默认的错误的信息 + * 默认的失败状态码 {@link StateCodeEnum#ERROR} + * @param data 数据 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getErrorResultWrapper(T data) { + return AuthResultWrapper.builder() + .code(StateCodeEnum.ERROR.getCode()) + .msg(StateCodeEnum.ERROR.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取默认的失败的信息 + * 默认的失败状态码 {@link StateCodeEnum#FAILURE} + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getFailureResultWrapper() { + return getCustomResultWrapper(StateCodeEnum.FAILURE); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param stateCode 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getCustomResultWrapper(StateCodeEnum stateCode) { + return getCustomResultWrapper(null, stateCode); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param data 业务数据 + * @param stateCode 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getCustomResultWrapper(T data, StateCodeEnum stateCode) { + return AuthResultWrapper.builder() + .code(stateCode.getCode()) + .msg(stateCode.getMsg()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + + + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param data 业务数据 + * @param code 状态码 + * @param msg 提示信息 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getCustomResultWrapper(T data, int code, String msg) { + return AuthResultWrapper.builder() + .code(code) + .msg(msg) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * 默认的成功状态码 {@link StateCodeEnum#SUCCESS} + * @param code 状态码 + * @param msg 提示信息 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getCustomResultWrapper(int code, String msg) { + return AuthResultWrapper.builder() + .code(code) + .msg(msg) + .data(null) + .timestamp(System.currentTimeMillis()) + .build(); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param baseMsg 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getCustomResultWrapper(BaseAuthMsg baseMsg) { + return getCustomResultWrapper(null, baseMsg); + } + + /** + * 获取约定好的自定义的成功信息,方便前端业务特殊处理 + * @param data 业务数据 + * @param baseMsg 状态码信息 + * @param 泛型 + * @return ResultWrapper + */ + public static AuthResultWrapper getCustomResultWrapper(T data, BaseAuthMsg baseMsg) { + return AuthResultWrapper.builder() + .code(baseMsg.getCode()) + .msg(baseMsg.getMessage()) + .data(data) + .timestamp(System.currentTimeMillis()) + .build(); + } + + + /** + * 验证返回结果是否成功, + * @param authResultWrapper 返回包装类 + * @param 泛型 + * @return boolean + */ + public static boolean isSuccess(AuthResultWrapper authResultWrapper) { + if(null == authResultWrapper){ + return false; + } + + return StateCodeEnum.SUCCESS.getCode() == authResultWrapper.getCode(); + } + + + /** + * 请求状态枚举 + * + * @author Parker + * @date 2021年12月30日15:29:29 + */ + @Getter + @AllArgsConstructor + public static enum StateCodeEnum { + + /** 请求状态枚举 */ + + SUCCESS(0, "请求成功"), + + SUCCESS_200(200, "请求成功"), + + FAILURE(-1, "操作失败"), + + ERROR(-1, "服务器异常"); + + private final int code; + private final String msg; + } + + + /** + * 后台请求状态枚举 + * + * @author liuhongzhen + */ + @Getter + @AllArgsConstructor + private enum BackStateEnum { + + /** 请求状态枚举 */ + SUCCESS(200, "操作成功"), + + ERROR(-1, "服务器异常"); + + private final int code; + private final String msg; + } + +} diff --git a/opsli-plugins/opsli-plugins-security/src/main/resources/META-INF/spring.factories b/opsli-plugins/opsli-plugins-security/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..48ddd52 --- /dev/null +++ b/opsli-plugins/opsli-plugins-security/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.opsli.plugins.security.SecurityConfig + diff --git a/opsli-plugins/opsli-plugins-sms/pom.xml b/opsli-plugins/opsli-plugins-sms/pom.xml new file mode 100644 index 0000000..270ab7b --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/pom.xml @@ -0,0 +1,27 @@ + + + + opsli-plugins + org.opsliframework.boot + 1.0.0 + ../pom.xml + + + 4.0.0 + opsli-plugins-sms + ${project.parent.version} + + 1.2.0 + + + + + cn.javaer.aliyun + aliyun-sms + ${aliyun-sms.version} + + + + diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/SmsConfig.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/SmsConfig.java new file mode 100644 index 0000000..5cf6586 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/SmsConfig.java @@ -0,0 +1,47 @@ +/** + * 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.plugins.sms; + +import cn.hutool.extra.spring.SpringUtil; +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.sms.service.SmsService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; + +/** + * Redisson自动化配置 + * + * @author Parker + * @date 2019/6/19 下午11:55 + */ +@Slf4j +@Configuration +public class SmsConfig { + + @Bean + public void initRedisPushSubHandler(){ + Map beansOfType = SpringUtil.getBeansOfType(SmsService.class); + for (Map.Entry smsServiceEntry : beansOfType.entrySet()) { + SmsService smsService = smsServiceEntry.getValue(); + // 加入集合 + SmsFactory.put(smsService); + } + } + +} + diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/SmsFactory.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/SmsFactory.java new file mode 100644 index 0000000..7032ad3 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/SmsFactory.java @@ -0,0 +1,62 @@ +/** + * 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.plugins.sms; + +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.sms.service.SmsService; +import org.opsli.plugins.sms.enums.SmsType; +import org.opsli.plugins.sms.exceptions.SmsException; +import org.opsli.plugins.sms.model.SmsModel; +import org.opsli.plugins.sms.msg.SmsMsgCodeEnum; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +/** + * 短信工厂 + * + * @author 周鹏程 + * @date 2021/8/27 14:09 + */ +@Slf4j +public final class SmsFactory { + + /** 执行器集合 */ + private final static Map HANDLE_MAP = new ConcurrentHashMap<>(); + + static void put(SmsService smsService){ + if(null == smsService){ + return; + } + // 加入集合 + HANDLE_MAP.put(smsService.getType(), smsService); + } + + /** + * 发送消息 + * 注:需要做好异常处理 + * @param smsModel 短信model + */ + public static void sendSms(SmsType type, SmsModel smsModel){ + SmsService smsService = HANDLE_MAP.get(type); + if(smsService == null){ + throw new SmsException(SmsMsgCodeEnum.CODE_ERROR_SMS_HANDLER); + } + smsService.sendSms(smsModel); + } + +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/conf/AliYunSmsProperties.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/conf/AliYunSmsProperties.java new file mode 100644 index 0000000..15d46a5 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/conf/AliYunSmsProperties.java @@ -0,0 +1,43 @@ +/** + * 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.plugins.sms.conf; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 阿里云 配置文件 + * + * @author yanxiaojian + * @date 2021-06-10 + **/ +@Data +@EqualsAndHashCode(callSuper = false) +@Component +@ConfigurationProperties(prefix = AliYunSmsProperties.PROP_PREFIX) +public class AliYunSmsProperties { + + public static final String PROP_PREFIX = "sms.aliyun"; + + /** 主账号id */ + private String accessKeyId; + + /** 密钥 */ + private String accessKeySecret; + +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/enums/SmsType.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/enums/SmsType.java new file mode 100644 index 0000000..e732acd --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/enums/SmsType.java @@ -0,0 +1,43 @@ +/** + * 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.plugins.sms.enums; + +/** + * 短信类型 + * + * @author 周鹏程 + * @date 2021年8月27日13:49:25 + */ +public enum SmsType { + + /** SMS 服务 */ + ALIYUN("阿里云"), + + ; + + private final String desc; + + + public String getDesc() { + return this.desc; + } + + // ================= + + SmsType(final String desc) { + this.desc = desc; + } +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/exceptions/SmsException.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/exceptions/SmsException.java new file mode 100644 index 0000000..729d4f7 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/exceptions/SmsException.java @@ -0,0 +1,37 @@ +/** + * 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.plugins.sms.exceptions; + + +import org.opsli.common.base.msg.BaseMsg; +import org.opsli.common.exception.ServiceException; + +/** + * 短信异常 + * + * @author 周鹏程 + * @date 2021年8月27日14:27:35 + */ +public class SmsException extends ServiceException { + + public SmsException(Integer code, String errorMessage) { + super(code, errorMessage); + } + + public SmsException(BaseMsg msg) { + super(msg); + } +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/model/SmsModel.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/model/SmsModel.java new file mode 100644 index 0000000..3ffe610 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/model/SmsModel.java @@ -0,0 +1,53 @@ +/** + * 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.plugins.sms.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 短信消息 + * + * @author 周鹏程 + * @date 2021/8/25 14:51 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SmsModel implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 手机号集合 */ + List tels; + + /** 模板编号 */ + String templateCode; + + /** 模板参数 */ + Map templateParam; + + /** 签名 可空默认为 公司名 */ + String signName; + +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/msg/SmsMsgCodeEnum.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/msg/SmsMsgCodeEnum.java new file mode 100644 index 0000000..f294f27 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/msg/SmsMsgCodeEnum.java @@ -0,0 +1,72 @@ +/** + * 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.plugins.sms.msg; + + +import org.opsli.common.base.msg.BaseMsg; + +/** + * 业务状态码 + * 组成描述: 错误级别(1位) + 模块标识(2位) + 具体错误码(3位) + * 0011000 + * + * 0 为通用正确 一切OK + * -1 为通用错误 + * + * 错误级别 + * + * + * 10000 ~ 10099 短信服务 + * 10100 ~ 10199 微信服务 + * + * @author Parker + * @date 2020-09-13 19:36 + */ +public enum SmsMsgCodeEnum implements BaseMsg { + + + /** 短信服务 */ + CODE_ERROR_SMS_HANDLER(310000, "未找到短息执行策略"), + CODE_ERROR_SMS_SIG_NAME_NULL(310001, "签名不可为空"), + CODE_ERROR_SMS_TEMPLATE_CODE_NULL(310002, "模版编号不可为空"), + CODE_ERROR_SMS_TEMPLATE_PARAM_NULL(310003, "模版参数不可为空"), + CODE_ERROR_SMS_PHONE_NUMBERS_NULL(310004, "手机号不可为空"), + + CODE_ERROR_SMS_INIT(310010, "初始化参数异常"), + EXCEPTION_IS_PHONE(98010,"不是座机号码+手机号码(CharUtil中国)+ 400 + 800电话 + 手机号号码(香港)! "), + + + ; + + private final int code; + private final String message; + + SmsMsgCodeEnum(int code, String message){ + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + @Override + public String getMessage() { + return this.message; + } +} + diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/service/SmsService.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/service/SmsService.java new file mode 100644 index 0000000..9342b54 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/service/SmsService.java @@ -0,0 +1,43 @@ +/** + * 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.plugins.sms.service; + + +import org.opsli.plugins.sms.enums.SmsType; +import org.opsli.plugins.sms.model.SmsModel; + +/** + * sms发送服务 + * + * @author 周鹏程 + * @date 2021年8月27日14:08:09 + */ +public interface SmsService { + + + /** + * 获得类型 + * @return SmsType + */ + SmsType getType(); + + /** + * 发送消息 + * @param smsModel 短信model + */ + void sendSms(SmsModel smsModel); + +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/service/impl/AliYunSmsServiceImpl.java b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/service/impl/AliYunSmsServiceImpl.java new file mode 100644 index 0000000..7c38fef --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/java/org/opsli/plugins/sms/service/impl/AliYunSmsServiceImpl.java @@ -0,0 +1,121 @@ +/** + * 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.plugins.sms.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.PhoneUtil; +import cn.hutool.core.util.StrUtil; +import cn.javaer.aliyun.sms.SmsClient; +import cn.javaer.aliyun.sms.SmsTemplate; +import lombok.extern.slf4j.Slf4j; +import org.opsli.plugins.sms.conf.AliYunSmsProperties; +import org.opsli.plugins.sms.enums.SmsType; +import org.opsli.plugins.sms.exceptions.SmsException; +import org.opsli.plugins.sms.model.SmsModel; +import org.opsli.plugins.sms.msg.SmsMsgCodeEnum; +import org.opsli.plugins.sms.service.SmsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * 阿里云 sms发送 + * + * @author yanxiaojian + * @date 2021年8月27日14:09:13 + */ +@Slf4j +@Service +public class AliYunSmsServiceImpl implements SmsService { + + @Autowired + private AliYunSmsProperties aliyunSmsProperties; + + @Override + public SmsType getType() { + return SmsType.ALIYUN; + } + + @Override + public void sendSms(SmsModel smsModel) { + // 发送短信 + this.sendSms(smsModel.getSignName(), smsModel.getTemplateCode(), smsModel.getTemplateParam(), + smsModel.getTels()); + } + + /** + * 发送信息 + * @param templateCode SMS_153055065 + * @param templateParam {"code":"1111"} + * @param phoneNumbers 支持对多个手机号码发送短信,手机号码之间以英文逗号(,)分隔。上限为1000个手机号码 + */ + private void sendSms(String signName, String templateCode, Map templateParam, List phoneNumbers){ + // 验证参数 + verify(signName, templateCode, templateParam, phoneNumbers); + + if(StrUtil.isEmpty(aliyunSmsProperties.getAccessKeyId()) || + StrUtil.isEmpty(aliyunSmsProperties.getAccessKeySecret())){ + // 初始化参数异常 + throw new SmsException(SmsMsgCodeEnum.CODE_ERROR_SMS_INIT); + } + + SmsClient smsClient = new SmsClient(aliyunSmsProperties.getAccessKeyId(), + aliyunSmsProperties.getAccessKeySecret()); + + // 发送信息 + SmsTemplate smsTemplate = SmsTemplate.builder() + .signName(signName) + .templateCode(templateCode) + .templateParam(templateParam) + .phoneNumbers(phoneNumbers) + .build(); + smsClient.send(smsTemplate); + } + + /** + * 验证 + * @param signName 签名 + * @param templateCode 模版编号 + * @param templateParam 模版参数 + * @param phoneNumbers 手机号 + */ + private void verify(String signName, String templateCode, Map templateParam, List phoneNumbers){ + if(StrUtil.isEmpty(signName)){ + // 签名不可为空 + throw new SmsException(SmsMsgCodeEnum.CODE_ERROR_SMS_SIG_NAME_NULL); + } + + if(StrUtil.isEmpty(templateCode)){ + // 模版编号不可为空 + throw new SmsException(SmsMsgCodeEnum.CODE_ERROR_SMS_TEMPLATE_CODE_NULL); + } + + if(CollUtil.isEmpty(phoneNumbers)){ + // 手机号不可为空 + throw new SmsException(SmsMsgCodeEnum.CODE_ERROR_SMS_PHONE_NUMBERS_NULL); + } + for (String tel : phoneNumbers) { + boolean isPhone = PhoneUtil.isPhone(tel); + if(!isPhone){ + // 不是座机号码+手机号码(CharUtil中国)+ 400 + 800电话 + 手机号号码(香港) + throw new SmsException(SmsMsgCodeEnum.EXCEPTION_IS_PHONE); + } + } + } + +} diff --git a/opsli-plugins/opsli-plugins-sms/src/main/resources/META-INF/spring.factories b/opsli-plugins/opsli-plugins-sms/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..69a2b09 --- /dev/null +++ b/opsli-plugins/opsli-plugins-sms/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.opsli.plugins.sms.SmsConfig diff --git a/opsli-plugins/pom.xml b/opsli-plugins/pom.xml index 831183f..9228056 100644 --- a/opsli-plugins/pom.xml +++ b/opsli-plugins/pom.xml @@ -23,6 +23,8 @@ opsli-plugins-waf opsli-plugins-crypto opsli-plugins-email + opsli-plugins-sms + opsli-plugins-security diff --git a/opsli-starter/src/main/resources/application-dev.yaml b/opsli-starter/src/main/resources/application-dev.yaml index a06c426..fc715ff 100644 --- a/opsli-starter/src/main/resources/application-dev.yaml +++ b/opsli-starter/src/main/resources/application-dev.yaml @@ -7,7 +7,7 @@ server: spring: #redis 配置 redis: - database: 0 + database: 8 host: 10.0.0.28 password: '123456' port: 6379 @@ -84,6 +84,15 @@ opsli: web: upload-path: var/files +# 短信 +sms: + # 阿里云 + aliyun: + # key + access-key-id: + # 密钥 + access-key-secret: + # 日志 logging: level: diff --git a/opsli-starter/src/main/resources/application-local.yaml b/opsli-starter/src/main/resources/application-local.yaml index c867dd7..8ab780e 100644 --- a/opsli-starter/src/main/resources/application-local.yaml +++ b/opsli-starter/src/main/resources/application-local.yaml @@ -84,6 +84,15 @@ opsli: web: upload-path: var/files +# 短信 +sms: + # 阿里云 + aliyun: + # key + access-key-id: LTAI3E9kZupue1Q7 + # 密钥 + access-key-secret: bZl15mNEXJqh6kWCBo9xkBSsCuuXt5 + # 日志 logging: level: diff --git a/opsli-starter/src/main/resources/application-prod.yaml b/opsli-starter/src/main/resources/application-prod.yaml index b71d876..38a2be5 100644 --- a/opsli-starter/src/main/resources/application-prod.yaml +++ b/opsli-starter/src/main/resources/application-prod.yaml @@ -79,6 +79,15 @@ opsli: web: upload-path: var/files +# 短信 +sms: + # 阿里云 + aliyun: + # key + access-key-id: + # 密钥 + access-key-secret: + # 日志 logging: level: diff --git a/opsli-starter/src/main/resources/application-test.yaml b/opsli-starter/src/main/resources/application-test.yaml index f2d57ad..7605a90 100644 --- a/opsli-starter/src/main/resources/application-test.yaml +++ b/opsli-starter/src/main/resources/application-test.yaml @@ -79,6 +79,15 @@ opsli: web: upload-path: var/files +# 短信 +sms: + # 阿里云 + aliyun: + # key + access-key-id: + # 密钥 + access-key-secret: + # 日志 logging: level: diff --git a/opsli-starter/src/main/resources/application.yaml b/opsli-starter/src/main/resources/application.yaml index 44d7769..d1eaf53 100644 --- a/opsli-starter/src/main/resources/application.yaml +++ b/opsli-starter/src/main/resources/application.yaml @@ -8,7 +8,7 @@ server: # 对于 Tomcat 头文件不限制大小 max-swallow-size: -1 servlet: - context-path: /opsli-boot + #context-path: /opsli-boot ## 专门针对 Controller层接口路径前缀全局配置 api: path: @@ -160,6 +160,30 @@ opsli: # 认证 auth: + # 凭证过期时间(天)-1 默认不过期,(如果要设置过期请先完成用户无需登录修改密码操作) + credentials-expired: -1 + # 排除过滤URL + url-exclusion: + # 未登陆状态下可以访问 + anonymous: + - "/captcha" + - "/system/slipCount" + - "/system/login" + - "/system/login-by-code" + # 无限制 + permit-all: + - "/api/*/common/public-key" + - "/api/*/common/email/create-code" + - "/api/*/common/mobile/create-code" + - "/swagger-ui.html" + - "/doc.html" + - "/swagger-resources/**" + - "/webjars/**" + - "/app/**" + - "/swagger/**" + - "/v2/api-docs" + - "/druid/**" + # 超级管理员账号 super-admin: system # 重置默认密码 密码至少包含大小写字母,数字,且不少于6位 @@ -171,10 +195,6 @@ opsli: secret: 53c0e33c9d4c5538969abf2fcf48351d # 有效时间 (分钟) 2小时 effective-time: 120 - # 排除过滤URL - url-exclusion: - - "/static/files/**" - - "/test.html" # 登录设置 login: diff --git a/opsli-starter/src/main/resources/ftl/email/email_code.ftl b/opsli-starter/src/main/resources/ftl/email/email_code.ftl new file mode 100644 index 0000000..ffd4caa --- /dev/null +++ b/opsli-starter/src/main/resources/ftl/email/email_code.ftl @@ -0,0 +1,14 @@ +

+
+
+

+ #(systemName)
邮箱验证码 +

+
+

尊敬的用户:

+

您的邮箱验证代码为: #(verificationCode)

+

本验证代码在 #(expiredDate) 之前有效

+
+
+
+
diff --git a/pom.xml b/pom.xml index 95b34b5..a9c82ab 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ https://www.opsli.com - 一个基于springboot、vue、ant design、集成代码生成器的Java开源快速开发框架,微服务平台。 + 一个基于springboot、vue、element-ui、集成代码生成器的Java开源快速开发框架。 @@ -15,7 +15,7 @@ parker - Parker Chou + Parker Zhou meet.parker@foxmail.com @@ -34,7 +34,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + 2.5.6 @@ -59,11 +59,11 @@ UTF-8 UTF-8 1.8 - 2.3.3.RELEASE + 2.5.6 true 1.2.83 - 3.4.0 + 3.5.2 1.3.0 3.10.3 @@ -72,7 +72,6 @@ 3.9.0 3.15.4 1.6.2 - 3.3.1 1.69 @@ -81,15 +80,19 @@ 8.0.28 4.0 11.2.0.3 - 42.2.6 + 42.3.3 5.7.14 30.0-android - 2.8.0 + 2.11.0 3.11 1.27 1.6.2 + 1.2.9 + 3.18.2 + 1.9.4 + 2.12.5 @@ -113,6 +116,27 @@ ${spring-boot.version} pom import + + + + ch.qos.logback + logback-access + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + + + mysql + mysql-connector-java + + @@ -150,13 +174,6 @@ ${pagehelper.version} - - - org.crazycake - shiro-redis-spring-boot-starter - ${shiro.redis.version} - - com.alibaba @@ -215,6 +232,19 @@ ${jna.version} + + + com.google.protobuf + protobuf-java + ${protobuf-java.version} + + + + com.jfinal + enjoy + 4.9.06 + + @@ -273,14 +303,20 @@ org.apache.commons commons-lang3 - ${commons.lang3.version} org.apache.commons commons-pool2 + + commons-beanutils + commons-beanutils + ${beanutils.version} + + + com.google.guava @@ -304,7 +340,7 @@ com.alibaba transmittable-thread-local - 2.12.5 + ${transmittable.version} @@ -314,6 +350,7 @@ ${hutool.version} + org.bouncycastle @@ -335,6 +372,23 @@ ${email.version} + + + ch.qos.logback + logback-access + ${logback.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + ch.qos.logback + logback-core + ${logback.version} + + @@ -342,7 +396,7 @@ com.upyun java-sdk - 4.2.2 + 4.2.3 provided true @@ -351,7 +405,7 @@ com.aliyun.oss aliyun-sdk-oss - 3.6.0 + 3.15.1 provided true