├── .gitignore ├── pic ├── alipay.jpg ├── wechat.jpg ├── qq_group.jpg ├── wechat_group.jpg ├── wechat_pay.jpg ├── 20230122174113.png ├── 20230122174148.png └── 20230122174204.png ├── .gitattributes ├── src └── main │ ├── java │ └── com │ │ └── suke │ │ └── czx │ │ ├── modules │ │ ├── msg │ │ │ ├── component │ │ │ │ ├── SendMessage.java │ │ │ │ ├── entity │ │ │ │ │ └── MessageBody.java │ │ │ │ ├── SendMessageAbstract.java │ │ │ │ └── AliyunNewSendMessageComponent.java │ │ │ ├── mapper │ │ │ │ ├── XMessageServiceMapper.java │ │ │ │ ├── XMessageServiceSendRecordMapper.java │ │ │ │ ├── XMessageServiceTemplateConfigMapper.java │ │ │ │ └── XMessageServiceTemplateMapper.java │ │ │ ├── service │ │ │ │ ├── XMessageServiceTemplateService.java │ │ │ │ ├── XMessageServiceTemplateConfigService.java │ │ │ │ ├── XMessageServiceService.java │ │ │ │ ├── XMessageServiceSendRecordService.java │ │ │ │ └── impl │ │ │ │ │ ├── XMessageServiceTemplateServiceImpl.java │ │ │ │ │ ├── XMessageServiceTemplateConfigServiceImpl.java │ │ │ │ │ └── XMessageServiceServiceImpl.java │ │ │ ├── entity │ │ │ │ ├── SendMsg.java │ │ │ │ ├── XMessageServiceTemplateConfig.java │ │ │ │ ├── XMessageServiceTemplate.java │ │ │ │ ├── XMessageService.java │ │ │ │ └── XMessageServiceSendRecord.java │ │ │ ├── api │ │ │ │ └── ApiXMessageServiceController.java │ │ │ └── controller │ │ │ │ ├── XMessageServiceSendRecordController.java │ │ │ │ └── XMessageServiceController.java │ │ ├── oss │ │ │ ├── mapper │ │ │ │ ├── SysOssSettingMapper.java │ │ │ │ └── SysOssMapper.java │ │ │ ├── service │ │ │ │ ├── SysOssSettingService.java │ │ │ │ ├── SysOssService.java │ │ │ │ └── impl │ │ │ │ │ ├── SysOssServiceImpl.java │ │ │ │ │ └── SysOssSettingServiceImpl.java │ │ │ ├── entity │ │ │ │ ├── SysOss.java │ │ │ │ └── SysOssSetting.java │ │ │ ├── cloud │ │ │ │ ├── OSSFactory.java │ │ │ │ ├── ICloudStorage.java │ │ │ │ └── QiniuCloudStorageService.java │ │ │ └── controller │ │ │ │ ├── SysOssController.java │ │ │ │ └── SysOssSettingController.java │ │ ├── application │ │ │ ├── annotation │ │ │ │ ├── ApplicationAuth.java │ │ │ │ └── ApplicationAuthAspect.java │ │ │ ├── mapper │ │ │ │ └── XApplicationMapper.java │ │ │ ├── service │ │ │ │ ├── XApplicationService.java │ │ │ │ └── impl │ │ │ │ │ └── XApplicationServiceImpl.java │ │ │ ├── entity │ │ │ │ └── XApplication.java │ │ │ └── controller │ │ │ │ └── XApplicationController.java │ │ ├── sys │ │ │ ├── vo │ │ │ │ ├── RouterInfo.java │ │ │ │ ├── UserInfoVO.java │ │ │ │ ├── RouterMetaVO.java │ │ │ │ └── SysMenuNewVO.java │ │ │ ├── mapper │ │ │ │ ├── SysMenuNewMapper.java │ │ │ │ ├── SysLoginLogMapper.java │ │ │ │ ├── SysLogMapper.java │ │ │ │ ├── SysUserMapper.java │ │ │ │ ├── SysRoleMenuMapper.java │ │ │ │ ├── SysUserRoleMapper.java │ │ │ │ ├── SysRolePermissionMapper.java │ │ │ │ ├── SysPermissionMapper.java │ │ │ │ └── SysRoleMapper.java │ │ │ ├── service │ │ │ │ ├── SysLogService.java │ │ │ │ ├── SysUserRoleService.java │ │ │ │ ├── SysLoginLogService.java │ │ │ │ ├── SysRoleMenuService.java │ │ │ │ ├── SysRolePermissionService.java │ │ │ │ ├── SysMenuNewService.java │ │ │ │ ├── impl │ │ │ │ │ ├── SysLoginLogServiceImpl.java │ │ │ │ │ ├── SysLogServiceImpl.java │ │ │ │ │ ├── SysRoleMenuServiceImpl.java │ │ │ │ │ ├── SysRolePermissionServiceImpl.java │ │ │ │ │ ├── SysUserRoleServiceImpl.java │ │ │ │ │ ├── SysPermissionServiceImpl.java │ │ │ │ │ └── SysUserServiceImpl.java │ │ │ │ ├── SysPermissionService.java │ │ │ │ ├── SysUserService.java │ │ │ │ └── SysRoleService.java │ │ │ ├── entity │ │ │ │ ├── SysRolePermission.java │ │ │ │ ├── SysUserRole.java │ │ │ │ ├── SysRoleMenu.java │ │ │ │ ├── SysLoginLog.java │ │ │ │ ├── SysLog.java │ │ │ │ ├── SysMenuNew.java │ │ │ │ ├── SysRole.java │ │ │ │ ├── SysPermission.java │ │ │ │ └── SysUser.java │ │ │ └── controller │ │ │ │ └── SysLogController.java │ │ ├── param │ │ │ ├── mapper │ │ │ │ └── TbParamMapper.java │ │ │ ├── service │ │ │ │ └── TbParamService.java │ │ │ └── entity │ │ │ │ └── TbParam.java │ │ ├── gen │ │ │ ├── entity │ │ │ │ ├── InfoRmationSchema.java │ │ │ │ ├── TableEntity.java │ │ │ │ ├── ColumnEntity.java │ │ │ │ └── MakerConfigEntity.java │ │ │ ├── service │ │ │ │ ├── SysGenService.java │ │ │ │ └── impl │ │ │ │ │ └── SysGenServiceImpl.java │ │ │ ├── mapper │ │ │ │ └── SysGenMapper.java │ │ │ └── controller │ │ │ │ └── SysGenController.java │ │ ├── apk │ │ │ ├── mapper │ │ │ │ └── TbApkVersionMapper.java │ │ │ ├── service │ │ │ │ ├── TbApkVersionService.java │ │ │ │ └── impl │ │ │ │ │ └── TbApkVersionServiceImpl.java │ │ │ └── entity │ │ │ │ └── TbApkVersion.java │ │ └── tenancy │ │ │ ├── entity │ │ │ ├── TenancyBase.java │ │ │ └── TbPlatformTenancy.java │ │ │ ├── service │ │ │ ├── TbPlatformTenancyService.java │ │ │ └── impl │ │ │ │ └── TbPlatformTenancyServiceImpl.java │ │ │ └── mapper │ │ │ └── TbPlatformTenancyMapper.java │ │ ├── common │ │ ├── annotation │ │ │ ├── ShardingTable.java │ │ │ ├── AuthIgnore.java │ │ │ ├── ResourceAuth.java │ │ │ └── SysLog.java │ │ ├── shardingtable │ │ │ ├── ShardingQueryData.java │ │ │ └── ShardingQueryDataAspect.java │ │ ├── lock │ │ │ ├── NotDoubleSubmit.java │ │ │ ├── RedissonLock.java │ │ │ └── NotDoubleSubmitAOP.java │ │ ├── event │ │ │ ├── LoginLogEvent.java │ │ │ └── LoginLogListener.java │ │ ├── exception │ │ │ ├── CustomAuthenticationException.java │ │ │ ├── RRException.java │ │ │ └── RRExceptionHandler.java │ │ ├── utils │ │ │ ├── HttpContextUtils.java │ │ │ ├── URLConvertUtil.java │ │ │ ├── R.java │ │ │ ├── UserUtil.java │ │ │ ├── IPUtils.java │ │ │ ├── MPPageConvert.java │ │ │ ├── SpringContextUtils.java │ │ │ └── Constant.java │ │ └── aspect │ │ │ └── SysLogAspect.java │ │ ├── authentication │ │ ├── role │ │ │ └── PermissionEntity.java │ │ ├── handler │ │ │ ├── CustomAccessDeniedHandler.java │ │ │ ├── TokenAuthenticationFailHandler.java │ │ │ ├── CustomAuthenticationFailHandler.java │ │ │ ├── CustomLogoutSuccessHandler.java │ │ │ └── CustomAuthenticationSuccessHandler.java │ │ ├── detail │ │ │ ├── PermissionsService.java │ │ │ ├── CustomUserDetailsUser.java │ │ │ └── CustomUserDetailsService.java │ │ ├── provider │ │ │ └── CustomAuthorizationManager.java │ │ └── utils │ │ │ └── TokenUtils.java │ │ ├── Application.java │ │ ├── config │ │ ├── KaptchaConfig.java │ │ ├── SwaggerProperties.java │ │ ├── GlobalAsyncConfig.java │ │ ├── WebConfigurer.java │ │ ├── MyBatisPlusConfig.java │ │ ├── SwaggerConfig.java │ │ ├── RedisConfig.java │ │ ├── AuthIgnoreConfig.java │ │ └── PermissionConfig.java │ │ └── interceptor │ │ └── ValidateCodeFilter.java │ └── resources │ ├── banner.txt │ ├── template │ ├── menu.sql.vm │ ├── Mapper.java.vm │ ├── Service.java.vm │ ├── Mapper.xml.vm │ ├── ServiceImpl.java.vm │ ├── index.js.vm │ ├── Entity.java.vm │ └── Controller.java.vm │ ├── application-test.yml │ ├── application-dev.yml │ ├── application-pro.yml │ ├── generator.properties │ ├── logback-spring.xml │ ├── mapper │ └── gen │ │ └── SysGenMapper.xml │ └── application.yml └── doc └── updateLog.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | -------------------------------------------------------------------------------- /pic/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/alipay.jpg -------------------------------------------------------------------------------- /pic/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/wechat.jpg -------------------------------------------------------------------------------- /pic/qq_group.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/qq_group.jpg -------------------------------------------------------------------------------- /pic/wechat_group.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/wechat_group.jpg -------------------------------------------------------------------------------- /pic/wechat_pay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/wechat_pay.jpg -------------------------------------------------------------------------------- /pic/20230122174113.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/20230122174113.png -------------------------------------------------------------------------------- /pic/20230122174148.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/20230122174148.png -------------------------------------------------------------------------------- /pic/20230122174204.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzcheng90/x-springboot/HEAD/pic/20230122174204.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=java 2 | *.css linguist-language=java 3 | *.html linguist-language=java 4 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/component/SendMessage.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.component; 2 | 3 | 4 | import com.suke.czx.modules.msg.component.entity.MessageBody; 5 | 6 | public interface SendMessage { 7 | 8 | boolean sendMessage(MessageBody messageBody); 9 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/mapper/SysOssSettingMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.oss.entity.SysOssSetting; 5 | 6 | public interface SysOssSettingMapper extends BaseMapper { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/annotation/ShardingTable.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 分表注解 7 | */ 8 | @Documented 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 11 | public @interface ShardingTable { 12 | } -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ==================================================================================================================== 2 | 3 | 欢迎使用 x-springboot 快速开发平台 - Powered By Suke czx 4 | 5 | ==================================================================================================================== -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/service/SysOssSettingService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.oss.entity.SysOssSetting; 5 | 6 | public interface SysOssSettingService extends IService { 7 | 8 | void setDefault(SysOssSetting param); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/annotation/ApplicationAuth.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.annotation; 2 | 3 | import com.suke.czx.common.annotation.AuthIgnore; 4 | 5 | import java.lang.annotation.*; 6 | 7 | @Target(ElementType.METHOD) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Documented 10 | @AuthIgnore 11 | public @interface ApplicationAuth { 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/vo/RouterInfo.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @Description : 路由信息 9 | * @Date 12:47 10 | * @Author yzcheng90@qq.com 11 | **/ 12 | @Data 13 | public class RouterInfo { 14 | 15 | public UserInfoVO userInfo; 16 | 17 | public List menus; 18 | 19 | } -------------------------------------------------------------------------------- /src/main/resources/template/menu.sql.vm: -------------------------------------------------------------------------------- 1 | -- 菜单SQL 2 | INSERT INTO `sys_menu_new` (`parent_id`, `name`, `path`, `redirect`, `component`, `title`, `is_link`, `is_hide`, `is_keep_alive`, `is_affix`, `is_iframe`, `icon`, `roles`, `order_sort`, `disabled`) 3 | VALUES (0, '${pathName}', '/${pathName}', NULL, '${moduleName}/index', '${comments}', NULL, 0, 1, 0, 0, 'iconfont icon-caidan', 'admin', 4, 1); 4 | 5 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysMenuNewMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysMenuNew; 5 | 6 | /** 7 | * 菜单管理 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | */ 12 | public interface SysMenuNewMapper extends BaseMapper { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysLoginLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysLoginLog; 5 | 6 | /** 7 | * 登录日志 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | */ 12 | public interface SysLoginLogMapper extends BaseMapper { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysLog; 5 | 6 | /** 7 | * 系统日志 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2017-03-08 10:40:56 12 | */ 13 | public interface SysLogMapper extends BaseMapper { 14 | 15 | } -------------------------------------------------------------------------------- /src/main/resources/template/Mapper.java.vm: -------------------------------------------------------------------------------- 1 | package ${package}.${moduleName}.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import ${package}.${moduleName}.entity.${className}; 5 | 6 | /** 7 | * ${comments} 8 | * 9 | * @author ${author} 10 | * @email ${email} 11 | * @date ${datetime} 12 | */ 13 | public interface ${className}Mapper extends BaseMapper<${className}> { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/annotation/AuthIgnore.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * api接口,忽略Token验证 7 | * @author czx 8 | * @email yzcheng90@qq.com 9 | * @date 2017-03-23 15:44 10 | */ 11 | @Target({ElementType.TYPE,ElementType.METHOD}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface AuthIgnore { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/mapper/SysOssMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.oss.entity.SysOss; 5 | 6 | /** 7 | * 文件上传 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2017-03-25 12:13:26 12 | */ 13 | public interface SysOssMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/template/Service.java.vm: -------------------------------------------------------------------------------- 1 | package ${package}.${moduleName}.service; 2 | 3 | import ${package}.${moduleName}.entity.${className}; 4 | 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * ${comments} 9 | * 10 | * @author ${author} 11 | * @email ${email} 12 | * @date ${datetime} 13 | */ 14 | public interface ${className}Service extends IService<${className}> { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysUser; 5 | 6 | /** 7 | * 系统用户 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2016年9月18日 上午9:34:11 12 | */ 13 | public interface SysUserMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysLogService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysLog; 5 | 6 | /** 7 | * 系统日志 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2017-03-08 10:40:56 12 | */ 13 | public interface SysLogService extends IService { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/service/SysOssService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.oss.entity.SysOss; 5 | 6 | /** 7 | * 文件上传 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2017-03-25 12:13:26 12 | */ 13 | public interface SysOssService extends IService { 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/param/mapper/TbParamMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.param.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.param.entity.TbParam; 5 | 6 | /** 7 | * 参数管理 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2023-04-03 09:19:41 12 | */ 13 | public interface TbParamMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | type: com.zaxxer.hikari.HikariDataSource 4 | driver-class-name: com.mysql.cj.jdbc.Driver 5 | username: root 6 | password: root 7 | url: jdbc:mysql://localhost:3306/x_springboot?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/shardingtable/ShardingQueryData.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.shardingtable; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 分表查询注解 7 | * 只支持 @RequestParam Map params 这种参数类型 8 | */ 9 | @Documented 10 | @Target(ElementType.METHOD) // 表示注解可以应用于方法 11 | @Retention(RetentionPolicy.RUNTIME) // 表示注解在运行时可用 12 | public @interface ShardingQueryData { 13 | 14 | Class tableEntity(); 15 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/entity/InfoRmationSchema.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.entity; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | @Data 9 | @Builder 10 | public class InfoRmationSchema implements Serializable { 11 | 12 | private String tableName; 13 | private String engine; 14 | private String tableComment; 15 | private String createTime; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | type: com.zaxxer.hikari.HikariDataSource 4 | driver-class-name: com.mysql.cj.jdbc.Driver 5 | username: root 6 | password: PP55PP55 7 | url: jdbc:mysql://192.168.0.201:3306/x_springboot?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true 8 | -------------------------------------------------------------------------------- /src/main/resources/application-pro.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | type: com.zaxxer.hikari.HikariDataSource 4 | driver-class-name: com.mysql.cj.jdbc.Driver 5 | username: root 6 | password: 123456 7 | url: jdbc:mysql://192.168.0.201:3306/x_springboot?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true 8 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/apk/mapper/TbApkVersionMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.apk.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.apk.entity.TbApkVersion; 5 | 6 | /** 7 | * APK版本管理 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2023-01-26 20:32:33 12 | */ 13 | public interface TbApkVersionMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysRoleMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysRoleMenu; 5 | 6 | /** 7 | * 角色与菜单对应关系 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2016年9月18日 上午9:33:46 12 | */ 13 | public interface SysRoleMenuMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysUserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysUserRole; 5 | 6 | /** 7 | * 用户与角色对应关系 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2016年9月18日 上午9:34:46 12 | */ 13 | public interface SysUserRoleMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysUserRoleService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysUserRole; 5 | 6 | 7 | /** 8 | * 用户与角色对应关系 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2019年4月17日 13 | */ 14 | public interface SysUserRoleService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/apk/service/TbApkVersionService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.apk.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.apk.entity.TbApkVersion; 5 | 6 | /** 7 | * APK版本管理 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2023-01-26 20:32:33 12 | */ 13 | public interface TbApkVersionService extends IService { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/lock/NotDoubleSubmit.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.lock; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 基于token 7 | * 防用户重复提交注解 8 | */ 9 | @Target(ElementType.METHOD) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | public @interface NotDoubleSubmit { 13 | 14 | /** 15 | * 延时时间 在延时多久后可以再次提交,默认10秒 16 | * @return 秒 17 | */ 18 | int delaySeconds() default 10; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/mapper/XMessageServiceMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.msg.entity.XMessageService; 5 | 6 | /** 7 | * 短信服务 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2025-08-15 17:51:27 12 | */ 13 | public interface XMessageServiceMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/generator.properties: -------------------------------------------------------------------------------- 1 | #\u7C7B\u578B\u8F6C\u6362\uFF0C\u914D\u7F6E\u4FE1\u606F 2 | tinyint=Integer 3 | smallint=Integer 4 | mediumint=Integer 5 | int=Integer 6 | integer=Integer 7 | bigint=Long 8 | float=Float 9 | double=Double 10 | decimal=BigDecimal 11 | bit=Boolean 12 | 13 | char=String 14 | varchar=String 15 | tinytext=String 16 | text=String 17 | mediumtext=String 18 | longtext=String 19 | 20 | date=Date 21 | datetime=Date 22 | timestamp=Date -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/event/LoginLogEvent.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.event; 2 | 3 | import com.suke.czx.modules.sys.entity.SysLoginLog; 4 | import org.springframework.context.ApplicationEvent; 5 | 6 | /** 7 | * @Description 登录日志事件 8 | * @Date 11:29 9 | * @Author yzcheng90@qq.com 10 | **/ 11 | public class LoginLogEvent extends ApplicationEvent { 12 | 13 | public LoginLogEvent(SysLoginLog source) { 14 | super(source); 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysRolePermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysRolePermission; 5 | 6 | /** 7 | * 角色与权限对应关系 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2016年9月18日 上午9:33:46 12 | */ 13 | public interface SysRolePermissionMapper extends BaseMapper { 14 | 15 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysLoginLogService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysLog; 5 | import com.suke.czx.modules.sys.entity.SysLoginLog; 6 | 7 | /** 8 | * 登录日志 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | */ 13 | public interface SysLoginLogService extends IService { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysRoleMenuService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysRoleMenu; 5 | 6 | 7 | 8 | /** 9 | * 角色与菜单对应关系 10 | * 11 | * @author czx 12 | * @email object_czx@163.com 13 | * @date 2016年9月18日 上午9:42:30 14 | */ 15 | public interface SysRoleMenuService extends IService { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/mapper/XApplicationMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.application.entity.XApplication; 5 | 6 | /** 7 | * 应用服务 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2025-08-15 16:34:08 12 | */ 13 | public interface XApplicationMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/component/entity/MessageBody.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.component.entity; 2 | 3 | import com.suke.czx.modules.msg.entity.XMessageService; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper = true) 10 | public class MessageBody extends XMessageService { 11 | 12 | public String mobile; 13 | public String code; 14 | public String template; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/service/XApplicationService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.service; 2 | 3 | import com.suke.czx.modules.application.entity.XApplication; 4 | 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * 应用服务 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2025-08-15 16:34:08 13 | */ 14 | public interface XApplicationService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysRolePermissionService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysRolePermission; 5 | 6 | 7 | /** 8 | * 角色与权限对应关系 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2016年9月18日 上午9:42:30 13 | */ 14 | public interface SysRolePermissionService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/annotation/ResourceAuth.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | 6 | /** 7 | *接口权限验证注解 8 | */ 9 | @Target({ElementType.TYPE, ElementType.METHOD}) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | public @interface ResourceAuth { 13 | /** 14 | * 接口名 15 | */ 16 | String value() default ""; 17 | 18 | /** 19 | * 模块 20 | */ 21 | String module() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/XMessageServiceTemplateService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service; 2 | 3 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplate; 4 | 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * 短信模板 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2025-08-15 17:48:07 13 | */ 14 | public interface XMessageServiceTemplateService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/mapper/XMessageServiceSendRecordMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.msg.entity.XMessageServiceSendRecord; 5 | 6 | /** 7 | * 短信发送记录(按月分表) 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2025-08-15 17:40:53 12 | */ 13 | public interface XMessageServiceSendRecordMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/exception/CustomAuthenticationException.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.exception; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | /** 6 | * @author czx 7 | * @title: CustomAuthenticationException 8 | * @projectName x-springboot 9 | * @date 2019/12/2416:45 10 | */ 11 | public class CustomAuthenticationException extends AuthenticationException { 12 | 13 | public CustomAuthenticationException(String msg){ 14 | super(msg); 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/mapper/XMessageServiceTemplateConfigMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplateConfig; 5 | 6 | /** 7 | * 短信模板配置 8 | * 9 | * @author czx 10 | * @email object_czx@163.com 11 | * @date 2025-08-15 17:53:22 12 | */ 13 | public interface XMessageServiceTemplateConfigMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/XMessageServiceTemplateConfigService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service; 2 | 3 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplateConfig; 4 | 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * 短信模板配置 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2025-08-15 17:53:22 13 | */ 14 | public interface XMessageServiceTemplateConfigService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/role/PermissionEntity.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.role; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 接口权限类 7 | */ 8 | @Data 9 | public class PermissionEntity { 10 | 11 | /** 12 | * 接口描述名称 13 | */ 14 | private String name; 15 | /** 16 | * 接口URL名称 17 | */ 18 | private String englishName; 19 | /** 20 | * 完整URL 21 | */ 22 | private String url; 23 | /** 24 | * 模块名 25 | */ 26 | private String moduleName; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysMenuNewService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysMenuNew; 5 | import com.suke.czx.modules.sys.vo.SysMenuNewVO; 6 | 7 | import java.util.List; 8 | 9 | 10 | /** 11 | * 菜单管理 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | */ 16 | public interface SysMenuNewService extends IService { 17 | 18 | List getUserMenu(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/template/Mapper.xml.vm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #foreach($column in $columns) 9 | 10 | #end 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/service/impl/SysOssServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.oss.entity.SysOss; 5 | import com.suke.czx.modules.oss.mapper.SysOssMapper; 6 | import com.suke.czx.modules.oss.service.SysOssService; 7 | import org.springframework.stereotype.Service; 8 | 9 | 10 | 11 | @Service 12 | public class SysOssServiceImpl extends ServiceImpl implements SysOssService { 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/vo/UserInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.vo; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @Description : 用户信息 7 | * @Date 12:50 8 | * @Author yzcheng90@qq.com 9 | **/ 10 | @Data 11 | public class UserInfoVO { 12 | 13 | public String userId; 14 | public String userName; 15 | public String name; 16 | public String loginIp; 17 | public String photo; 18 | public String time; 19 | public String[] roles; 20 | public String[] authBtnList; 21 | public String roleNames; 22 | 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/HttpContextUtils.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | import jakarta.servlet.http.HttpServletRequest; 4 | import org.springframework.web.context.request.RequestContextHolder; 5 | import org.springframework.web.context.request.ServletRequestAttributes; 6 | 7 | import java.util.Objects; 8 | 9 | public class HttpContextUtils { 10 | 11 | public static HttpServletRequest getHttpServletRequest() { 12 | return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysLoginLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.sys.entity.SysLoginLog; 5 | import com.suke.czx.modules.sys.mapper.SysLoginLogMapper; 6 | import com.suke.czx.modules.sys.service.SysLoginLogService; 7 | import org.springframework.stereotype.Service; 8 | 9 | 10 | @Service 11 | public class SysLoginLogServiceImpl extends ServiceImpl implements SysLoginLogService { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/vo/RouterMetaVO.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @Description : 路由元信息 9 | * @Date 12:26 10 | * @Author yzcheng90@qq.com 11 | **/ 12 | @Data 13 | public class RouterMetaVO implements Serializable { 14 | 15 | public String title; 16 | public String isLink; 17 | public boolean isHide; 18 | public boolean isKeepAlive; 19 | public boolean isAffix; 20 | public boolean isIframe; 21 | public String icon; 22 | public String roles; 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/Application.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | 8 | @Slf4j 9 | @EnableScheduling 10 | @SpringBootApplication 11 | public class Application { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(Application.class, args); 15 | log.info("==================X-SpringBoot启动成功================"); 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.sys.entity.SysLog; 5 | import com.suke.czx.modules.sys.mapper.SysLogMapper; 6 | import com.suke.czx.modules.sys.service.SysLogService; 7 | import lombok.AllArgsConstructor; 8 | import org.springframework.stereotype.Service; 9 | 10 | 11 | @Service 12 | @AllArgsConstructor 13 | public class SysLogServiceImpl extends ServiceImpl implements SysLogService { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/annotation/SysLog.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * 系统日志注解 11 | * 12 | * @author czx 13 | * @email object_czx@163.com 14 | * @date 2017年3月8日 上午10:19:56 15 | */ 16 | @Target(ElementType.METHOD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Documented 19 | public @interface SysLog { 20 | 21 | String value() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/XMessageServiceService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service; 2 | 3 | import com.suke.czx.modules.msg.entity.XMessageService; 4 | 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * 短信服务 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2025-08-15 17:51:27 13 | */ 14 | public interface XMessageServiceService extends IService { 15 | 16 | void saveInfo(XMessageService param); 17 | 18 | void updateInfo(XMessageService param); 19 | 20 | void deleteInfo(XMessageService param); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysPermissionService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysPermission; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 接口权限管理 10 | * 11 | * @author czx 12 | * @email object_czx@163.com 13 | * @date 2023-05-17 14:48:21 14 | */ 15 | public interface SysPermissionService extends IService { 16 | 17 | List getPermissionListByUserId(String userId); 18 | 19 | List getAllList(); 20 | 21 | void clearCache(); 22 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/tenancy/entity/TenancyBase.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.tenancy.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | @Data 9 | public class TenancyBase { 10 | 11 | @Schema(description = "渠道ID") 12 | @JsonProperty(value = "tenancyId") 13 | public Integer tenancyId; 14 | 15 | @TableField(exist = false) 16 | @Schema(description = "渠道名称") 17 | @JsonProperty(value = "tenancyName") 18 | public String tenancyName; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/component/SendMessageAbstract.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.component; 2 | 3 | import com.suke.czx.modules.msg.component.entity.MessageBody; 4 | import lombok.extern.slf4j.Slf4j; 5 | 6 | @Slf4j 7 | public abstract class SendMessageAbstract implements SendMessage { 8 | 9 | /** 10 | * 发送短信失败 11 | * @param messageBody 短信参数 12 | * @param errorInfo 错误信息 13 | */ 14 | public void sendMessageFail(MessageBody messageBody, String errorInfo){ 15 | log.error("短信发送失败:{}", errorInfo); 16 | //FeishuNoticeComponent.sendErrorNotice(entries.getStr("Message")); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/service/SysGenService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.suke.czx.modules.gen.entity.InfoRmationSchema; 7 | import com.suke.czx.modules.gen.entity.MakerConfigEntity; 8 | 9 | public interface SysGenService extends IService { 10 | 11 | IPage queryTableList(IPage page, QueryWrapper entityWrapper); 12 | 13 | void generatorCode(MakerConfigEntity config); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/template/ServiceImpl.java.vm: -------------------------------------------------------------------------------- 1 | package ${package}.${moduleName}.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import org.springframework.stereotype.Service; 5 | import ${package}.${moduleName}.mapper.${className}Mapper; 6 | import ${package}.${moduleName}.entity.${className}; 7 | import ${package}.${moduleName}.service.${className}Service; 8 | 9 | 10 | /** 11 | * ${comments} 12 | * 13 | * @author ${author} 14 | * @email ${email} 15 | * @date ${datetime} 16 | */ 17 | @Service 18 | public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${className}> implements ${className}Service { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysRolePermission.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 角色与权限对应关系 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | */ 16 | @Data 17 | @TableName("sys_role_permission") 18 | @Schema(description = "角色与权限对应关系") 19 | public class SysRolePermission implements Serializable { 20 | 21 | @Schema(description = "角色ID") 22 | public Long roleId; 23 | 24 | @Schema(description = "权限ID") 25 | public String permissionId; 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysUserRole.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 用户与角色对应关系 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | */ 16 | @Data 17 | @Schema(description = "用户与角色对应关系") 18 | public class SysUserRole implements Serializable { 19 | 20 | @TableId 21 | public Long id; 22 | 23 | @Schema(description = "用户ID") 24 | public String userId; 25 | 26 | @Schema(description = "角色ID") 27 | public Long roleId; 28 | 29 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/entity/TableEntity.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 表数据 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2016年12月20日 上午12:02:55 13 | */ 14 | @Data 15 | public class TableEntity { 16 | //表的名称 17 | private String tableName; 18 | //表的备注 19 | private String comments; 20 | //表的主键 21 | private ColumnEntity pk; 22 | //表的列名(不包含主键) 23 | private List columns; 24 | 25 | //类名(第一个字母大写),如:sys_user => SysUser 26 | private String className; 27 | //类名(第一个字母小写),如:sys_user => sysUser 28 | private String classNameMin; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysRoleMenuServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.sys.entity.SysRoleMenu; 5 | import com.suke.czx.modules.sys.mapper.SysRoleMenuMapper; 6 | import com.suke.czx.modules.sys.service.SysRoleMenuService; 7 | import org.springframework.stereotype.Service; 8 | 9 | 10 | /** 11 | * 角色与菜单对应关系 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2016年9月18日 上午9:44:35 16 | */ 17 | @Service 18 | public class SysRoleMenuServiceImpl extends ServiceImpl implements SysRoleMenuService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/apk/service/impl/TbApkVersionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.apk.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.apk.entity.TbApkVersion; 5 | import com.suke.czx.modules.apk.mapper.TbApkVersionMapper; 6 | import com.suke.czx.modules.apk.service.TbApkVersionService; 7 | import org.springframework.stereotype.Service; 8 | 9 | 10 | /** 11 | * APK版本管理 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2023-01-26 20:32:33 16 | */ 17 | @Service 18 | public class TbApkVersionServiceImpl extends ServiceImpl implements TbApkVersionService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/entity/SysOss.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.entity; 2 | 3 | import com.baomidou.mybatisplus.extension.activerecord.Model; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | 9 | 10 | 11 | /** 12 | * 文件上传 13 | * 14 | * @author czx 15 | * @email object_czx@163.com 16 | * @date 2017-03-25 12:13:26 17 | */ 18 | @Data 19 | @EqualsAndHashCode(callSuper = true) 20 | public class SysOss extends Model implements Serializable { 21 | private static final long serialVersionUID = 1L; 22 | 23 | // 24 | private Long id; 25 | //URL地址 26 | private String url; 27 | //创建时间 28 | private Date createDate; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/service/impl/XApplicationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import org.springframework.stereotype.Service; 5 | import com.suke.czx.modules.application.mapper.XApplicationMapper; 6 | import com.suke.czx.modules.application.entity.XApplication; 7 | import com.suke.czx.modules.application.service.XApplicationService; 8 | 9 | 10 | /** 11 | * 应用服务 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2025-08-15 16:34:08 16 | */ 17 | @Service 18 | public class XApplicationServiceImpl extends ServiceImpl implements XApplicationService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/XMessageServiceSendRecordService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service; 2 | 3 | import com.suke.czx.modules.msg.entity.SendMsg; 4 | import com.suke.czx.modules.msg.entity.XMessageService; 5 | import com.suke.czx.modules.msg.entity.XMessageServiceSendRecord; 6 | 7 | import com.baomidou.mybatisplus.extension.service.IService; 8 | 9 | /** 10 | * 短信发送记录(按月分表) 11 | * 12 | * @author czx 13 | * @email object_czx@163.com 14 | * @date 2025-08-15 17:40:53 15 | */ 16 | public interface XMessageServiceSendRecordService extends IService { 17 | 18 | boolean autoServiceSendMessage(SendMsg msg); 19 | 20 | boolean sendMessage(XMessageService messageService, SendMsg msg); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysRolePermissionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.sys.entity.SysRolePermission; 5 | import com.suke.czx.modules.sys.mapper.SysRolePermissionMapper; 6 | import com.suke.czx.modules.sys.service.SysRolePermissionService; 7 | import org.springframework.stereotype.Service; 8 | 9 | 10 | /** 11 | * 角色与权限对应关系 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2016年9月18日 上午9:44:35 16 | */ 17 | @Service 18 | public class SysRolePermissionServiceImpl extends ServiceImpl implements SysRolePermissionService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysUserService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysUser; 5 | 6 | 7 | /** 8 | * 系统用户 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2016年9月18日 上午9:43:39 13 | */ 14 | public interface SysUserService extends IService { 15 | 16 | /** 17 | * 修改密码 18 | * 19 | * @param userId 用户ID 20 | * @param password 原密码 21 | * @param newPassword 新密码 22 | */ 23 | int updatePassword(String userId, String password, String newPassword); 24 | 25 | void saveUserRole(SysUser user); 26 | 27 | void updateUserRole(SysUser user); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysUserRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.sys.entity.SysUserRole; 5 | import com.suke.czx.modules.sys.mapper.SysUserRoleMapper; 6 | import com.suke.czx.modules.sys.service.SysUserRoleService; 7 | import lombok.AllArgsConstructor; 8 | import org.springframework.stereotype.Service; 9 | 10 | 11 | /** 12 | * 用户与角色对应关系 13 | * 14 | * @author czx 15 | * @email object_czx@163.com 16 | * @date 2019年4月17日 17 | */ 18 | @Service 19 | @AllArgsConstructor 20 | public class SysUserRoleServiceImpl extends ServiceImpl implements SysUserRoleService { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/impl/XMessageServiceTemplateServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import org.springframework.stereotype.Service; 5 | import com.suke.czx.modules.msg.mapper.XMessageServiceTemplateMapper; 6 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplate; 7 | import com.suke.czx.modules.msg.service.XMessageServiceTemplateService; 8 | 9 | 10 | /** 11 | * 短信模板 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2025-08-15 17:48:07 16 | */ 17 | @Service 18 | public class XMessageServiceTemplateServiceImpl extends ServiceImpl implements XMessageServiceTemplateService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/entity/ColumnEntity.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.entity; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 列的属性 7 | * 8 | * @author czx 9 | * @email object_czx@163.com 10 | * @date 2016年12月20日 上午12:01:45 11 | */ 12 | @Data 13 | public class ColumnEntity { 14 | //表名 15 | private String tableName; 16 | //列名 17 | private String columnName; 18 | //列名类型 19 | private String dataType; 20 | //列名备注 21 | private String columnComment; 22 | // 23 | private String columnKey; 24 | 25 | //属性名称(第一个字母大写),如:user_name => UserName 26 | private String attrName; 27 | //属性名称(第一个字母小写),如:user_name => userName 28 | private String attrNameMin; 29 | //属性类型 30 | private String attrType; 31 | //auto_increment 32 | private String extra; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/entity/SendMsg.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.entity; 2 | 3 | import com.suke.czx.modules.tenancy.entity.TenancyBase; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper = true) 10 | public class SendMsg extends TenancyBase { 11 | 12 | /** 13 | * 手机号 14 | */ 15 | public String mobile; 16 | /** 17 | * 验证码 18 | */ 19 | public String code; 20 | 21 | /** 22 | * 内容,如果验证码不为空,优先使用验证码进行替换 23 | */ 24 | public String content; 25 | /** 26 | * 服务ID 27 | */ 28 | public Integer serviceId; 29 | 30 | /** 31 | * 模板ID 32 | */ 33 | public Integer templateId; 34 | 35 | /** 36 | * 模板类型 37 | */ 38 | public String templateType; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysRoleMenu.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | 4 | import com.baomidou.mybatisplus.annotation.IdType; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | import lombok.Data; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | * 角色与菜单对应关系 14 | * 15 | * @author czx 16 | * @email object_czx@163.com 17 | */ 18 | @Data 19 | @TableName("sys_role_menu") 20 | @Schema(description = "角色与菜单对应关系") 21 | public class SysRoleMenu implements Serializable { 22 | 23 | @TableId(type = IdType.AUTO) 24 | public Long id; 25 | 26 | @Schema(description = "角色ID") 27 | public Long roleId; 28 | 29 | @Schema(description = "菜单ID") 30 | public Long menuId; 31 | 32 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/SysRoleService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.suke.czx.modules.sys.entity.SysRole; 5 | 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * 角色 11 | * 12 | * @author czx 13 | * @email object_czx@163.com 14 | * @date 2016年9月18日 上午9:42:52 15 | */ 16 | public interface SysRoleService extends IService { 17 | List getRoleListByUserId(String userId); 18 | 19 | /** 20 | * 查询用户创建的角色ID列表 21 | */ 22 | List queryRoleIdList(String createUserId); 23 | 24 | List queryUserRoleIdList(String userId); 25 | 26 | void deleteBath(Long id); 27 | 28 | void saveRoleMenu(SysRole role); 29 | 30 | void updateRoleMenu(SysRole role); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/vo/SysMenuNewVO.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.vo; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | /** 10 | * @Description : 菜单管理 11 | * @Date 12:26 12 | * @Author yzcheng90@qq.com 13 | **/ 14 | @Data 15 | @Schema(description = "菜单管理") 16 | public class SysMenuNewVO implements Serializable { 17 | 18 | public Long menuId; 19 | public Long parentId; 20 | public String path; 21 | public String name; 22 | public String menuType; 23 | public String component; 24 | public String redirect; 25 | public String title; 26 | public int orderSort; 27 | public boolean isLink; 28 | 29 | public RouterMetaVO meta; 30 | 31 | public List children; 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/impl/XMessageServiceTemplateConfigServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import org.springframework.stereotype.Service; 5 | import com.suke.czx.modules.msg.mapper.XMessageServiceTemplateConfigMapper; 6 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplateConfig; 7 | import com.suke.czx.modules.msg.service.XMessageServiceTemplateConfigService; 8 | 9 | 10 | /** 11 | * 短信模板配置 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2025-08-15 17:53:22 16 | */ 17 | @Service 18 | public class XMessageServiceTemplateConfigServiceImpl extends ServiceImpl implements XMessageServiceTemplateConfigService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/tenancy/service/TbPlatformTenancyService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.tenancy.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.suke.czx.modules.tenancy.entity.TbPlatformTenancy; 7 | 8 | /** 9 | * 渠道管理 10 | * 11 | * @author czx 12 | * @email object_czx@163.com 13 | * @date 2024-11-29 14:48:31 14 | */ 15 | public interface TbPlatformTenancyService extends IService { 16 | 17 | IPage pageList(IPage tbPlatformTenancyIPage, QueryWrapper queryWrapper); 18 | 19 | void setDefault(TbPlatformTenancy tenancy); 20 | 21 | TbPlatformTenancy getDefaultTenancy(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/updateLog.md: -------------------------------------------------------------------------------- 1 | ### v5.0 2 | - springboot 版本升级到 2.7.7 3 | - mybatis-plus 版本升级到 3.5.2 4 | - 项目重构,精简代码 5 | - 前台UI换成 vue-cli 6 | 7 | ### v3.2 8 | - 修复上传文件时报匿名无权限 9 | - 修复一些删除报错问题 10 | - 修复 [issues #15](https://github.com/yzcheng90/X-SpringBoot/issues/15) 11 | 12 | ### v3.1 13 | - 修复代码生成一些错误依赖 [issues #10](https://github.com/yzcheng90/X-SpringBoot/issues/10) 14 | - 修改 security token 保存方式 15 | 16 | ### v3.0 17 | - 项目部分重构,精简部分代码 18 | - springboot 版本升级到 2.1.8 19 | - 移除shiro 安全框架 20 | - 新增spring security 安全框架 21 | 22 | ### v2.1.2 23 | - 修复配置sso信息的时候更新不成功 24 | 25 | ### v2.1.1 26 | - 群里及issues中提到的一些bug修复 27 | 28 | ### v2.1 29 | - 加入代码生成模块 30 | - 加入APP管理模块 31 | 32 | ### v2.0 33 | - 大量重构代码,精简了大量代码减少第三方依赖。 34 | - 引入lombok 大量简化了代码 35 | - 引入MyBatis Plus 大量简化了SQL 36 | - 引入hutool 工具包 规范工具类 37 | - 引入minio 分布式文件系统 38 | - 前后端完全脱离,前端代码可单独部署 39 | - 支持密码和手机号 获取token 40 | - 核心框架升级到Spring Boot 2.1.3 41 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/mapper/SysGenMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.suke.czx.modules.gen.entity.ColumnEntity; 7 | import com.suke.czx.modules.gen.entity.InfoRmationSchema; 8 | import org.apache.ibatis.annotations.Param; 9 | 10 | import java.util.List; 11 | 12 | public interface SysGenMapper extends BaseMapper { 13 | 14 | IPage queryTableList(IPage page, @Param("ew") QueryWrapper entityWrapper); 15 | 16 | InfoRmationSchema queryTableList(@Param("ew") QueryWrapper entityWrapper); 17 | 18 | List queryColumns(@Param("ew") QueryWrapper entityWrapper); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/event/LoginLogListener.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.event; 2 | 3 | import com.suke.czx.modules.sys.entity.SysLoginLog; 4 | import com.suke.czx.modules.sys.service.SysLoginLogService; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.event.EventListener; 8 | import org.springframework.scheduling.annotation.Async; 9 | 10 | /** 11 | * @Description 登录日志监听器 12 | * @Date 11:28 13 | * @Author yzcheng90@qq.com 14 | **/ 15 | @Configuration 16 | @RequiredArgsConstructor 17 | public class LoginLogListener { 18 | 19 | private final SysLoginLogService sysLoginLogService; 20 | 21 | @Async 22 | @EventListener(LoginLogEvent.class) 23 | public void saveSysLog(LoginLogEvent event) { 24 | SysLoginLog sysLoginLog = (SysLoginLog) event.getSource(); 25 | sysLoginLogService.save(sysLoginLog); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/entity/MakerConfigEntity.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.entity; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author czx 7 | * @title: MakerConfigEntity 8 | * @projectName zhjg 9 | * @description: 10 | * @date 2020/6/168:57 11 | */ 12 | @Data 13 | public class MakerConfigEntity { 14 | 15 | private String tableName; 16 | private String mainPath; 17 | private String packagePath; 18 | private String moduleName; 19 | private String requestMapping; 20 | private boolean useRestful; 21 | private boolean useHump; 22 | private String filePath; 23 | private String uiFilePath; 24 | private String author; 25 | private String email; 26 | 27 | private boolean fileController; 28 | private boolean fileServiceImpl; 29 | private boolean fileMapper; 30 | private boolean fileMapperXml; 31 | private boolean fileEntity; 32 | private boolean genUi; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/mapper/XMessageServiceTemplateMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplate; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | 8 | /** 9 | * 短信模板 10 | * 11 | * @author czx 12 | * @email object_czx@163.com 13 | * @date 2025-08-15 17:48:07 14 | */ 15 | public interface XMessageServiceTemplateMapper extends BaseMapper { 16 | 17 | 18 | @Select("select t2.* from x_message_service_template_config t1,x_message_service_template t2 " + 19 | "where " + 20 | "t1.template_id = t2.template_id " + 21 | "and t1.template_id = #{templateId} " + 22 | "and t1.service_id = #{serviceId} and t2.is_enable = 1 limit 1;") 23 | XMessageServiceTemplate queryTemplate(@Param("templateId") Integer templateId,@Param("serviceId") Integer serviceId); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/KaptchaConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import com.google.code.kaptcha.impl.DefaultKaptcha; 4 | import com.google.code.kaptcha.util.Config; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | import java.util.Properties; 9 | 10 | 11 | /** 12 | * 生成验证码配置 13 | * 14 | * @author czx 15 | * @email object_czx@163.com 16 | * @date 2017-04-20 19:22 17 | */ 18 | @Configuration 19 | public class KaptchaConfig { 20 | 21 | @Bean 22 | public DefaultKaptcha producer() { 23 | Properties properties = new Properties(); 24 | properties.put("kaptcha.border", "no"); 25 | properties.put("kaptcha.textproducer.font.color", "black"); 26 | properties.put("kaptcha.textproducer.char.space", "5"); 27 | Config config = new Config(properties); 28 | DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); 29 | defaultKaptcha.setConfig(config); 30 | return defaultKaptcha; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysPermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysPermission; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 接口权限管理 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2023-05-17 14:48:21 16 | */ 17 | public interface SysPermissionMapper extends BaseMapper { 18 | 19 | @Select("SELECT * from sys_permission where permission_id in (SELECT t1.permission_id from sys_role_permission t1,sys_user_role t2 where t1.role_id = t2.role_id and t2.user_id = #{userId})") 20 | List getPermissionListByUserId(@Param("userId") String userId); 21 | 22 | 23 | @Select("select * from (SELECT t1.*,t2.title as menuName from sys_permission t1 left join sys_menu_new t2 on t1.menu_id = t2.menu_id ) t ") 24 | List getAllList(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/mapper/gen/SysGenMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 26 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/SwaggerProperties.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * @Description 9 | * @Date 16:01 10 | * @Author yzcheng90@qq.com 11 | **/ 12 | @Data 13 | @Component 14 | @ConfigurationProperties(value = "swagger") 15 | public class SwaggerProperties { 16 | 17 | /** 18 | * 是否开启swagger,生产环境一般关闭,所以这里定义一个变量 19 | */ 20 | private Boolean enable = false; 21 | 22 | /** 23 | * 项目信息 24 | */ 25 | private String title = ""; 26 | 27 | /** 28 | * 描述信息 29 | */ 30 | private String description = ""; 31 | 32 | /** 33 | * 版本信息 34 | */ 35 | private String version = ""; 36 | 37 | /** 38 | * 作者 39 | */ 40 | private String author = ""; 41 | 42 | /** 43 | * url 44 | */ 45 | private String url = ""; 46 | 47 | /** 48 | * email 49 | */ 50 | private String email = ""; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/entity/XMessageServiceTemplateConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | import lombok.Data; 9 | 10 | import java.io.Serializable; 11 | 12 | 13 | /** 14 | * 短信模板配置 15 | * 16 | * @author czx 17 | * @email object_czx@163.com 18 | * @date 2025-08-15 17:53:22 19 | */ 20 | @Data 21 | @TableName("x_message_service_template_config") 22 | public class XMessageServiceTemplateConfig implements Serializable { 23 | 24 | public static final long serialVersionUID = 1L; 25 | 26 | @TableId(type = IdType.INPUT) 27 | @Schema(description = "服务ID") 28 | @JsonProperty(value = "serviceId") 29 | public Integer serviceId; 30 | 31 | @Schema(description = "模板ID") 32 | @JsonProperty(value = "templateId") 33 | public Integer templateId; 34 | 35 | 36 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/param/service/TbParamService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.param.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.suke.czx.modules.param.entity.TbParam; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 参数管理 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2023-04-03 09:19:41 16 | */ 17 | public interface TbParamService extends IService { 18 | 19 | List getParamList(String tenancyId); 20 | 21 | Object getValue(String key); 22 | 23 | Object getValue(String tenancyId, String key); 24 | 25 | Object getObjectValue(String tenancyId, String key, String field); 26 | 27 | Object getValue(Long tenancyId, String key); 28 | 29 | IPage pageInfo(IPage iPage, QueryWrapper queryWrapper); 30 | 31 | void saveInfo(TbParam param); 32 | 33 | void updateInfo(TbParam param); 34 | 35 | void deleteInfo(TbParam param); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysPermissionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.suke.czx.modules.sys.entity.SysPermission; 5 | import com.suke.czx.modules.sys.mapper.SysPermissionMapper; 6 | import com.suke.czx.modules.sys.service.SysPermissionService; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | 12 | /** 13 | * 接口权限管理 14 | * 15 | * @author czx 16 | * @email object_czx@163.com 17 | * @date 2023-05-17 14:48:21 18 | */ 19 | @Service 20 | public class SysPermissionServiceImpl extends ServiceImpl implements SysPermissionService { 21 | 22 | @Override 23 | public List getPermissionListByUserId(String userId) { 24 | return baseMapper.getPermissionListByUserId(userId); 25 | } 26 | 27 | @Override 28 | public List getAllList() { 29 | return baseMapper.getAllList(); 30 | } 31 | 32 | public void clearCache() { 33 | log.debug("删除用户权限缓存"); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/service/impl/SysOssSettingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.suke.czx.modules.oss.entity.SysOssSetting; 6 | import com.suke.czx.modules.oss.mapper.SysOssSettingMapper; 7 | import com.suke.czx.modules.oss.service.SysOssSettingService; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | @Service 12 | public class SysOssSettingServiceImpl extends ServiceImpl implements SysOssSettingService { 13 | 14 | @Override 15 | @Transactional 16 | public void setDefault(SysOssSetting param) { 17 | SysOssSetting ossSetting = baseMapper.selectById(param.getId()); 18 | if (ossSetting != null) { 19 | baseMapper.update(new UpdateWrapper().set("status", 0)); 20 | ossSetting.setStatus(1); 21 | baseMapper.updateById(ossSetting); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/exception/RRException.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.exception; 2 | 3 | /** 4 | * 自定义异常 5 | * 6 | * @author czx 7 | * @email object_czx@163.com 8 | * @date 2016年10月27日 下午10:11:27 9 | */ 10 | public class RRException extends RuntimeException { 11 | private static final long serialVersionUID = 1L; 12 | 13 | private String msg; 14 | private int code = 500; 15 | 16 | public RRException(String msg) { 17 | super(msg); 18 | this.msg = msg; 19 | } 20 | 21 | public RRException(String msg, Throwable e) { 22 | super(msg, e); 23 | this.msg = msg; 24 | } 25 | 26 | public RRException(String msg, int code) { 27 | super(msg); 28 | this.msg = msg; 29 | this.code = code; 30 | } 31 | 32 | public RRException(String msg, int code, Throwable e) { 33 | super(msg, e); 34 | this.msg = msg; 35 | this.code = code; 36 | } 37 | 38 | public String getMsg() { 39 | return msg; 40 | } 41 | 42 | public void setMsg(String msg) { 43 | this.msg = msg; 44 | } 45 | 46 | public int getCode() { 47 | return code; 48 | } 49 | 50 | public void setCode(int code) { 51 | this.code = code; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/GlobalAsyncConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Primary; 8 | import org.springframework.core.task.AsyncTaskExecutor; 9 | import org.springframework.core.task.support.TaskExecutorAdapter; 10 | import org.springframework.scheduling.annotation.EnableAsync; 11 | 12 | import java.util.concurrent.Executors; 13 | 14 | /** 15 | * 全局异步任务配置类 16 | */ 17 | @Slf4j 18 | @EnableAsync 19 | @Configuration 20 | public class GlobalAsyncConfig { 21 | 22 | @Bean 23 | @Primary 24 | public AsyncTaskExecutor asyncTaskExecutor() { 25 | return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor()); 26 | } 27 | 28 | @Bean 29 | public TomcatProtocolHandlerCustomizer tomcatProtocolHandlerCustomizer() { 30 | return protocolHandler -> protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysLoginLog.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import com.fasterxml.jackson.annotation.JsonFormat; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | import lombok.Data; 9 | 10 | import java.util.Date; 11 | 12 | 13 | /** 14 | * 登录日志 15 | * 16 | * @author czx 17 | * @email object_czx@163.com 18 | */ 19 | @Data 20 | @Schema(description = "登录日志") 21 | @TableName("tb_login_log") 22 | public class SysLoginLog { 23 | 24 | @TableId(value = "log_id", type = IdType.ASSIGN_UUID) 25 | public String logId; 26 | 27 | @Schema(description = "用户名") 28 | public String username; 29 | 30 | @Schema(description = "用户操作") 31 | public String optionName; 32 | 33 | @Schema(description = "操作终端") 34 | public String optionTerminal; 35 | 36 | @Schema(description = "IP地址") 37 | public String optionIp; 38 | 39 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 40 | @Schema(description = "创建时间") 41 | public Date optionTime; 42 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/tenancy/mapper/TbPlatformTenancyMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.tenancy.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.suke.czx.modules.tenancy.entity.TbPlatformTenancy; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.apache.ibatis.annotations.Select; 9 | 10 | /** 11 | * 渠道管理 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2024-11-29 14:48:31 16 | */ 17 | public interface TbPlatformTenancyMapper extends BaseMapper { 18 | 19 | @Select("select * from (select t1.*,t2.tenancy_name tenancyParentName from tb_platform_tenancy t1\n" + 20 | "left join tb_platform_tenancy t2\n" + 21 | " on t1.tenancy_pid=t2.tenancy_id) t ${ew.customSqlSegment}") 22 | IPage pageList(IPage tbPlatformTenancyIPage, @Param("ew") QueryWrapper queryWrapper); 23 | 24 | @Select("select * from tb_platform_tenancy where is_default = 1 limit 1 ") 25 | TbPlatformTenancy getDefaultTenancy(); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysLog.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.fasterxml.jackson.annotation.JsonFormat; 6 | import io.swagger.v3.oas.annotations.media.Schema; 7 | import lombok.Data; 8 | 9 | import java.util.Date; 10 | 11 | 12 | /** 13 | * 系统日志 14 | * 15 | * @author czx 16 | * @email object_czx@163.com 17 | * @date 2017-03-08 10:40:56 18 | */ 19 | @Data 20 | @Schema(description = "系统日志") 21 | public class SysLog { 22 | 23 | @TableId(type = IdType.AUTO) 24 | public Long id; 25 | 26 | @Schema(description = "用户名") 27 | public String username; 28 | 29 | @Schema(description = "用户操作") 30 | public String operation; 31 | 32 | @Schema(description = "请求方法") 33 | public String method; 34 | 35 | @Schema(description = "请求参数") 36 | public String params; 37 | 38 | @Schema(description = "执行时长(毫秒)") 39 | public Long time; 40 | 41 | @Schema(description = "IP地址") 42 | public String ip; 43 | 44 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 45 | @Schema(description = "创建时间") 46 | public Date createDate; 47 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysMenuNew.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import io.swagger.v3.oas.annotations.media.Schema; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * @Description 13 | * @Date 12:26 14 | * @Author yzcheng90@qq.com 15 | **/ 16 | @Data 17 | @TableName("sys_menu_new") 18 | @Schema(description = "菜单管理") 19 | public class SysMenuNew implements Serializable { 20 | 21 | @TableId(value = "menu_id", type = IdType.AUTO) 22 | @Schema(description = "菜单ID") 23 | public Long menuId; 24 | 25 | @Schema(description = "父菜单ID,一级菜单为0") 26 | public Long parentId; 27 | 28 | public String path; 29 | public String name; 30 | public String component; 31 | public String redirect; 32 | public String title; 33 | public String isLink; 34 | public boolean isHide; 35 | public boolean isKeepAlive; 36 | public boolean isAffix; 37 | public boolean isIframe; 38 | public String icon; 39 | public String roles; 40 | public int orderSort; 41 | public boolean disabled; 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/handler/CustomAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.handler; 2 | 3 | import cn.hutool.json.JSONUtil; 4 | import com.suke.czx.common.utils.R; 5 | import jakarta.servlet.ServletException; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.security.access.AccessDeniedException; 11 | import org.springframework.security.web.access.AccessDeniedHandler; 12 | 13 | import java.io.IOException; 14 | import java.io.PrintWriter; 15 | 16 | /** 17 | * 自定义权限不足处理器 18 | */ 19 | public class CustomAccessDeniedHandler implements AccessDeniedHandler { 20 | 21 | @Override 22 | public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { 23 | response.setStatus(HttpStatus.OK.value()); 24 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 25 | PrintWriter writer = response.getWriter(); 26 | writer.write(JSONUtil.toJsonStr(R.error(HttpStatus.FORBIDDEN.value(), accessDeniedException.getMessage()))); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/lock/RedissonLock.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.lock; 2 | 3 | import jakarta.annotation.Resource; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * 使用Redisson加锁 11 | */ 12 | @Slf4j 13 | @Component 14 | public class RedissonLock { 15 | 16 | @Resource 17 | private RedisLock redisLock; 18 | 19 | /** 20 | * Redission获取锁 21 | * 22 | * @param lockKey 23 | * @param delaySeconds 24 | * @param unit 25 | * @return 26 | */ 27 | public boolean lock(String lockKey, long delaySeconds, final TimeUnit unit) { 28 | boolean success = false; 29 | try { 30 | success = redisLock.lock(lockKey, lockKey, delaySeconds, unit); 31 | } catch (Exception e) { 32 | log.error("[RedissonLock][lock]>>>> 加锁异常: {}", e.getMessage()); 33 | } 34 | return success; 35 | } 36 | 37 | /** 38 | * Redission释放锁 39 | * 40 | * @param lockKey 锁名 41 | */ 42 | public void unlock(String lockKey) { 43 | boolean status = redisLock.unlock(lockKey, lockKey); 44 | log.debug("[RedissonLock][unlock]>>>> status: {} ", status); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/WebConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 7 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | /** 11 | * @Description 12 | * @Date 10:46 13 | * @Author yzcheng90@qq.com 14 | **/ 15 | @Configuration 16 | public class WebConfigurer implements WebMvcConfigurer { 17 | 18 | @Bean 19 | public ObjectMapper objectMapper() { 20 | return new ObjectMapper(); 21 | } 22 | 23 | @Override 24 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 25 | registry.addResourceHandler("/swagger-ui/**") 26 | .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") 27 | .resourceChain(false); 28 | } 29 | 30 | @Override 31 | public void addViewControllers(ViewControllerRegistry registry) { 32 | registry.addViewController("/swagger-ui/").setViewName("forward:/swagger-ui/index.html"); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /src/main/resources/template/index.js.vm: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request'; 2 | 3 | /** 4 | * ${comments} 5 | * 6 | * @author ${author} 7 | * @email ${email} 8 | * @date ${datetime} 9 | */ 10 | export function use${ModuleName}Api() { 11 | return { 12 | list: (params) => { 13 | return request({ 14 | url: '/${moduleName}/${requestMapping}/list', 15 | method: 'get', 16 | params 17 | }); 18 | }, 19 | add: (params) => { 20 | return request({ 21 | #if($useRestful) 22 | url: '/${moduleName}/${moduleName}/${requestMapping}', 23 | method: 'put', 24 | #else 25 | url: '/${moduleName}/${requestMapping}/save', 26 | method: 'post', 27 | #end 28 | data: params 29 | }); 30 | }, 31 | update: (params) => { 32 | return request({ 33 | #if($useRestful) 34 | url: '/${moduleName}/${moduleName}/${requestMapping}', 35 | method: 'put', 36 | #else 37 | url: '/${moduleName}/${requestMapping}/update', 38 | method: 'post', 39 | #end 40 | data: params 41 | }); 42 | }, 43 | delete: (params) => { 44 | return request({ 45 | #if($useRestful) 46 | url: '/${moduleName}/${moduleName}/${requestMapping}', 47 | method: 'delete', 48 | #else 49 | url: '/${moduleName}/${requestMapping}/delete', 50 | method: 'post', 51 | #end 52 | data: params 53 | }); 54 | } 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/handler/TokenAuthenticationFailHandler.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.handler; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.suke.czx.common.utils.R; 5 | import jakarta.servlet.http.HttpServletRequest; 6 | import jakarta.servlet.http.HttpServletResponse; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.security.core.AuthenticationException; 10 | import org.springframework.security.web.AuthenticationEntryPoint; 11 | import java.io.IOException; 12 | import java.io.PrintWriter; 13 | 14 | /** 15 | * @Description 认证失败处理类 16 | * @Date 23:11 17 | * @Author yzcheng90@qq.com 18 | **/ 19 | public class TokenAuthenticationFailHandler implements AuthenticationEntryPoint { 20 | 21 | @Override 22 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { 23 | ObjectMapper objectMapper = new ObjectMapper(); 24 | response.setStatus(HttpStatus.UNAUTHORIZED.value()); 25 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 26 | PrintWriter writer = response.getWriter(); 27 | writer.write(objectMapper.writeValueAsString(R.error(HttpStatus.UNAUTHORIZED.value(),authException.getMessage()))); 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/detail/PermissionsService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.detail; 2 | 3 | import com.suke.czx.authentication.role.PermissionEntity; 4 | import com.suke.czx.common.utils.Constant; 5 | import com.suke.czx.config.PermissionConfig; 6 | import com.suke.czx.modules.sys.entity.SysPermission; 7 | import com.suke.czx.modules.sys.service.SysPermissionService; 8 | import jakarta.annotation.Resource; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.Set; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * 用户角色 17 | */ 18 | @Slf4j 19 | @Service 20 | public class PermissionsService { 21 | 22 | @Resource 23 | private PermissionConfig permissionConfig; 24 | 25 | @Resource 26 | private SysPermissionService sysPermissionService; 27 | 28 | public Set getUserPermissions(String userId) { 29 | Set permissions; 30 | if (userId.equals(Constant.SUPER_ADMIN)) { 31 | permissions = permissionConfig.getPermissionEntities().stream().map(PermissionEntity::getEnglishName).collect(Collectors.toSet()); 32 | } else { 33 | permissions = sysPermissionService.getPermissionListByUserId(userId).stream().map(SysPermission::getEnglishName).collect(Collectors.toSet()); 34 | } 35 | return permissions; 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/detail/CustomUserDetailsUser.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.detail; 2 | 3 | import lombok.Getter; 4 | import org.springframework.security.core.GrantedAuthority; 5 | import org.springframework.security.core.userdetails.User; 6 | 7 | import java.io.Serializable; 8 | import java.util.Collection; 9 | 10 | /** 11 | * @Description : 自定义UserDetails 12 | * @Date 21:13 13 | * @Author yzcheng90@qq.com 14 | **/ 15 | @Getter 16 | public class CustomUserDetailsUser extends User implements Serializable { 17 | 18 | private final String userId; 19 | private final Integer tenancyId; 20 | 21 | public CustomUserDetailsUser(Integer tenancyId, String userId, String username, String password, Collection authorities) { 22 | super(username, password, authorities); 23 | this.userId = userId; 24 | this.tenancyId = tenancyId; 25 | } 26 | 27 | public CustomUserDetailsUser(Integer tenancyId, String userId, String username, String password, boolean enabled, boolean accountNonExpired, boolean accountNonLocked, boolean credentialsNonExpired, Collection authorities) { 28 | super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); 29 | this.userId = userId; 30 | this.tenancyId = tenancyId; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # Tomcat 2 | server: 3 | port: 8080 4 | 5 | spring: 6 | # 环境 dev|test|pro 7 | profiles: 8 | active: test 9 | # jackson时间格式化 10 | jackson: 11 | time-zone: GMT+8 12 | date-format: yyyy-MM-dd HH:mm:ss 13 | servlet: 14 | multipart: 15 | maxFileSize: 104857600 #100MB 16 | maxRequestSize: 104857600 #100MB 17 | data: 18 | redis: 19 | host: localhost 20 | port: 6379 21 | 22 | swagger: 23 | title: X-SpringBoot API 24 | description: API 描述 25 | version: 6.0.0 26 | author: czx 27 | url: https://github.com/yzcheng90/X-SpringBoot 28 | email: object_czx@163.com 29 | 30 | springdoc: 31 | api-docs: 32 | enabled: false # 开启OpenApi接口 33 | path: /v3/api-docs # 自定义路径,默认为 "/v3/api-docs" 34 | swagger-ui: 35 | enabled: false # 开启swagger界面,依赖OpenApi,需要OpenApi同时开启 36 | path: /swagger-ui/index.html # 自定义路径,默认为"/swagger-ui/index.html" 37 | 38 | # mybaits-plus配置 39 | mybatis-plus: 40 | # MyBatis Mapper所对应的XML文件位置 41 | mapper-locations: classpath:/mapper/**/*Mapper.xml 42 | global-config: 43 | # 关闭MP3.0自带的banner 44 | banner: false 45 | enable-sql-runner: true 46 | db-config: 47 | # 主键类型 0:数据库ID自增 1.未定义 2.用户输入 3 id_worker 4.uuid 5.id_worker字符串表示 48 | id-type: 0 49 | #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" 50 | field-strategy: 1 51 | # 默认数据库表下划线命名 52 | table-underline: true 53 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/api/ApiXMessageServiceController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.api; 2 | 3 | import com.suke.czx.common.base.AbstractController; 4 | import com.suke.czx.common.utils.R; 5 | import com.suke.czx.modules.application.annotation.ApplicationAuth; 6 | import com.suke.czx.modules.msg.entity.SendMsg; 7 | import com.suke.czx.modules.msg.service.XMessageServiceSendRecordService; 8 | import io.swagger.v3.oas.annotations.tags.Tag; 9 | import lombok.AllArgsConstructor; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | 16 | /** 17 | * 短信服务 18 | * 19 | * @author czx 20 | * @email object_czx@163.com 21 | * @date 2025-08-15 17:51:27 22 | */ 23 | @RestController 24 | @AllArgsConstructor 25 | @RequestMapping("/api/msg/service") 26 | @Tag(name = "XMessageServiceController", description = "短信服务") 27 | public class ApiXMessageServiceController extends AbstractController { 28 | 29 | private final XMessageServiceSendRecordService xMessageServiceSendRecordService; 30 | 31 | @ApplicationAuth 32 | @PostMapping("/send") 33 | public R list(@RequestBody SendMsg params) { 34 | boolean bool = xMessageServiceSendRecordService.autoServiceSendMessage(params); 35 | return R.ok().setData(bool); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/main/resources/template/Entity.java.vm: -------------------------------------------------------------------------------- 1 | package ${package}.${moduleName}.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import lombok.Data; 7 | 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | import com.fasterxml.jackson.annotation.JsonFormat; 12 | import io.swagger.v3.oas.annotations.media.Schema; 13 | import com.fasterxml.jackson.annotation.JsonProperty; 14 | 15 | #if(${hasBigDecimal}) 16 | import java.math.BigDecimal; 17 | #end 18 | 19 | 20 | /** 21 | * ${comments} 22 | * 23 | * @author ${author} 24 | * @email ${email} 25 | * @date ${datetime} 26 | */ 27 | @Data 28 | @TableName("${tableName}") 29 | public class ${className} implements Serializable { 30 | 31 | public static final long serialVersionUID = 1L; 32 | 33 | #foreach ($column in $columns) 34 | #if($column.columnKey != $null && $column.columnKey == "PRI") 35 | @TableId(type = IdType.ASSIGN_UUID) 36 | #end 37 | #if($column.attrType == "Date") 38 | @Schema(description = "$column.columnComment") 39 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 40 | #end 41 | #if($column.attrType != "Date") 42 | @Schema(description = "$column.columnComment") 43 | #end 44 | @JsonProperty(value = "$column.attrNameMin") 45 | public $column.attrType $column.attrNameMin; 46 | 47 | #end 48 | 49 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/entity/XApplication.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | import lombok.Data; 9 | 10 | import java.io.Serializable; 11 | 12 | 13 | /** 14 | * 应用服务 15 | * 16 | * @author czx 17 | * @email object_czx@163.com 18 | * @date 2025-08-15 16:34:08 19 | */ 20 | @Data 21 | @TableName("x_application") 22 | public class XApplication implements Serializable { 23 | 24 | public static final long serialVersionUID = 1L; 25 | 26 | @TableId(type = IdType.AUTO) 27 | @Schema(description = "应用ID") 28 | @JsonProperty(value = "appId") 29 | public Integer appId; 30 | 31 | @Schema(description = "AppKey") 32 | @JsonProperty(value = "appKey") 33 | public String appKey; 34 | 35 | @Schema(description = "应用名称") 36 | @JsonProperty(value = "appName") 37 | public String appName; 38 | 39 | @Schema(description = "AppSecret") 40 | @JsonProperty(value = "appSecret") 41 | public String appSecret; 42 | 43 | @Schema(description = "是否可用(1可用,0不可用)") 44 | @JsonProperty(value = "isEnable") 45 | public Integer isEnable; 46 | 47 | @Schema(description = "租户ID") 48 | @JsonProperty(value = "tenancyId") 49 | public String tenancyId; 50 | 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/URLConvertUtil.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | /** 4 | * @author czx 5 | * @title: URLConvertUtil 6 | * @projectName zhjg 7 | * @description: rest url 转驼峰 8 | * @date 2020/5/18 11:46 9 | */ 10 | public class URLConvertUtil { 11 | 12 | private static final char UNDERLINE = '/'; 13 | private static final String INDEX = "/{"; 14 | 15 | public static String convert(String url) { 16 | if(url.contains(INDEX)){ 17 | url = url.substring(0,url.indexOf(INDEX)); 18 | } 19 | StringBuilder sb = new StringBuilder(); 20 | for (int i=0;i { 7 | public R() { 8 | this.put("code", 0); 9 | this.put("msg", "success"); 10 | } 11 | 12 | public static R error() { 13 | return error(500, "服务未知异常"); 14 | } 15 | 16 | public static R error(String msg) { 17 | return error(500, msg); 18 | } 19 | 20 | public static R error(int code, String msg) { 21 | R r = new R(); 22 | r.put("code", code); 23 | r.put("msg", msg); 24 | return r; 25 | } 26 | 27 | public static R ok(String msg) { 28 | R r = new R(); 29 | r.put("msg", msg); 30 | return r; 31 | } 32 | 33 | public static R ok(String msg, String data) { 34 | R r = ok(msg); 35 | r.put("data", data); 36 | return r; 37 | } 38 | 39 | public static R ok(Map map) { 40 | R r = new R(); 41 | r.putAll(map); 42 | return r; 43 | } 44 | 45 | public static R ok() { 46 | return new R(); 47 | } 48 | 49 | public R setPage(Object value) { 50 | super.put("page", value); 51 | return this; 52 | } 53 | 54 | public R setData(Object value) { 55 | super.put("data", value); 56 | return this; 57 | } 58 | 59 | public R put(String key, Object value) { 60 | super.put(key, value); 61 | return this; 62 | } 63 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.suke.czx.modules.sys.entity.SysRole; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 角色管理 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2016年9月18日 上午9:33:33 16 | */ 17 | public interface SysRoleMapper extends BaseMapper { 18 | 19 | /** 20 | * 查询用户创建的角色ID列表 21 | */ 22 | @Select(" select role_id\n" + 23 | " from sys_role\n" + 24 | " where create_user_id = #{createUserId}") 25 | List queryRoleIdList(String createUserId); 26 | 27 | /** 28 | * 查询用户拥有的角色ID列表 29 | */ 30 | @Select("select role_id\n" + 31 | " from sys_user_role\n" + 32 | " where user_id = #{userId}") 33 | List queryUserRoleIdList(String userId); 34 | 35 | /** 36 | * 查询用户的所有菜单ID 37 | */ 38 | @Select("SELECT DISTINCT rm.menu_id\n" + 39 | " FROM sys_role_menu rm\n" + 40 | " LEFT JOIN sys_user_role ur ON ur.role_id = rm.role_id\n" + 41 | " where ur.user_id = #{userId}") 42 | List queryAllMenuId(String userId); 43 | 44 | 45 | @Select("select t2.* from sys_user_role t1 LEFT JOIN sys_role t2 on t1.role_id = t2.role_id where t1.user_id = #{userId}") 46 | List getRoleListByUserId(@Param("userId") String userId); 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/MyBatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor; 6 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 7 | import com.suke.czx.common.shardingtable.ShardingTableConfig; 8 | import jakarta.annotation.Resource; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.mybatis.spring.annotation.MapperScan; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.transaction.annotation.EnableTransactionManagement; 14 | 15 | @Slf4j 16 | @Configuration 17 | @EnableTransactionManagement 18 | @MapperScan(value = "com.suke.czx.modules.*.mapper") 19 | public class MyBatisPlusConfig { 20 | 21 | @Resource 22 | public ShardingTableConfig shardingTableHandler; 23 | 24 | /** 25 | * 添加分页插件 26 | */ 27 | @Bean 28 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 29 | // 拦截器 30 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 31 | // 动态表名插件 32 | DynamicTableNameInnerInterceptor dynamicTableNameInterceptor = new DynamicTableNameInnerInterceptor(shardingTableHandler); 33 | interceptor.addInnerInterceptor(dynamicTableNameInterceptor); 34 | // 分页插件 35 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加 36 | return interceptor; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/entity/XMessageServiceTemplate.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.suke.czx.modules.tenancy.entity.TenancyBase; 9 | import io.swagger.v3.oas.annotations.media.Schema; 10 | import lombok.Data; 11 | import lombok.EqualsAndHashCode; 12 | 13 | import java.io.Serializable; 14 | 15 | 16 | /** 17 | * 短信模板 18 | * 19 | * @author czx 20 | * @email object_czx@163.com 21 | * @date 2025-08-15 17:48:07 22 | */ 23 | @Data 24 | @EqualsAndHashCode(callSuper = true) 25 | @TableName("x_message_service_template") 26 | public class XMessageServiceTemplate extends TenancyBase implements Serializable { 27 | 28 | public static final long serialVersionUID = 1L; 29 | 30 | @TableId(type = IdType.AUTO) 31 | @Schema(description = "模板ID") 32 | @JsonProperty(value = "templateId") 33 | public Integer templateId; 34 | 35 | @Schema(description = "是否启用,1启动,0禁用") 36 | @JsonProperty(value = "isEnable") 37 | public Integer isEnable; 38 | 39 | @Schema(description = "备注") 40 | @JsonProperty(value = "remark") 41 | public String remark; 42 | 43 | @Schema(description = "模板内容") 44 | @JsonProperty(value = "templateContent") 45 | public String templateContent; 46 | 47 | @Schema(description = "模板类型(预留,比如验证码,营销)") 48 | @JsonProperty(value = "templateType") 49 | public String templateType; 50 | 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonFormat; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | import lombok.Data; 10 | 11 | import java.io.Serializable; 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | /** 16 | * 角色 17 | * 18 | * @author czx 19 | * @email object_czx@163.com 20 | */ 21 | @Data 22 | @Schema(description = "角色") 23 | @TableName("sys_role") 24 | public class SysRole implements Serializable { 25 | 26 | public static final long serialVersionUID = 1L; 27 | 28 | @Schema(description = "角色ID") 29 | @TableId(value = "role_id", type = IdType.AUTO) 30 | public Long roleId; 31 | 32 | @Schema(description = "角色名称") 33 | public String roleName; 34 | 35 | @Schema(description = "备注") 36 | public String remark; 37 | 38 | @Schema(description = "创建者ID") 39 | public String createUserId; 40 | 41 | @TableField(exist = false) 42 | @Schema(description = "创建者名称") 43 | public String createUserName; 44 | 45 | @Schema(description = "创建时间") 46 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 47 | public Date createTime; 48 | 49 | @Schema(description = "菜单ID") 50 | @TableField(exist = false) 51 | public List menuIdList; 52 | 53 | @Schema(description = "权限ID") 54 | @TableField(exist = false) 55 | public List permissionList; 56 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/UserUtil.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.suke.czx.authentication.detail.CustomUserDetailsUser; 5 | import lombok.SneakyThrows; 6 | import lombok.experimental.UtilityClass; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | 9 | /** 10 | * @Description 11 | * @Date 10:20 12 | * @Author yzcheng90@qq.com 13 | **/ 14 | @UtilityClass 15 | public class UserUtil { 16 | 17 | public CustomUserDetailsUser getUser() { 18 | Object object = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 19 | if (object != null) { 20 | return (CustomUserDetailsUser) object; 21 | } 22 | return null; 23 | } 24 | 25 | @SneakyThrows 26 | public String getUserId() { 27 | return getUser() == null ? null : getUser().getUserId(); 28 | } 29 | 30 | @SneakyThrows 31 | public Integer getUserTenancyId() { 32 | return getUser() == null ? null : getUser().getTenancyId(); 33 | } 34 | 35 | public boolean isAdmin(String userId) { 36 | return StrUtil.isNotEmpty(userId) && userId.equals(Constant.SUPER_ADMIN); 37 | } 38 | 39 | public boolean isAdmin() { 40 | return getUser() != null && getUser().getUserId().equals(Constant.SUPER_ADMIN); 41 | } 42 | 43 | public boolean isMiniAdmin() { 44 | return getUser() != null && getUser().getUserId().equals(Constant.SUPER_MINI_ADMIN); 45 | } 46 | 47 | public boolean isMiniAdmin(String userId) { 48 | return StrUtil.isNotEmpty(userId) && userId.equals(Constant.SUPER_MINI_ADMIN); 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import io.swagger.v3.oas.models.ExternalDocumentation; 4 | import io.swagger.v3.oas.models.OpenAPI; 5 | import io.swagger.v3.oas.models.info.Contact; 6 | import io.swagger.v3.oas.models.info.Info; 7 | import io.swagger.v3.oas.models.info.License; 8 | import jakarta.annotation.Resource; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.ComponentScan; 14 | import org.springframework.context.annotation.Configuration; 15 | 16 | /** 17 | * Created by czx on 2021/04/02. 18 | */ 19 | @ComponentScan(basePackages = {"com.suke.czx.modules"}) 20 | @Configuration 21 | public class SwaggerConfig { 22 | 23 | @Resource 24 | private SwaggerProperties swaggerProperties; 25 | 26 | @Bean 27 | public OpenAPI springShopOpenAPI() { 28 | return new OpenAPI() 29 | .info(new Info().title(swaggerProperties.getTitle()) 30 | .contact(new Contact()) 31 | .description(swaggerProperties.getDescription()) 32 | .version(swaggerProperties.getVersion()) 33 | .license(new License().name(swaggerProperties.getAuthor()).url(swaggerProperties.getUrl()))) 34 | .externalDocs(new ExternalDocumentation() 35 | .description(swaggerProperties.getEmail()) 36 | .url(swaggerProperties.getUrl())); 37 | } 38 | 39 | 40 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/service/impl/SysGenServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.suke.czx.common.utils.GenUtils; 7 | import com.suke.czx.modules.gen.entity.ColumnEntity; 8 | import com.suke.czx.modules.gen.entity.InfoRmationSchema; 9 | import com.suke.czx.modules.gen.entity.MakerConfigEntity; 10 | import com.suke.czx.modules.gen.mapper.SysGenMapper; 11 | import com.suke.czx.modules.gen.service.SysGenService; 12 | import lombok.AllArgsConstructor; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.List; 16 | 17 | @Service 18 | @AllArgsConstructor 19 | public class SysGenServiceImpl extends ServiceImpl implements SysGenService { 20 | 21 | private final SysGenMapper sysGenMapper; 22 | private final GenUtils genUtils; 23 | 24 | @Override 25 | public IPage queryTableList(IPage page, QueryWrapper entityWrapper) { 26 | return sysGenMapper.queryTableList(page, entityWrapper); 27 | } 28 | 29 | @Override 30 | public void generatorCode(MakerConfigEntity config) { 31 | //查询表信息 32 | InfoRmationSchema table = sysGenMapper.queryTableList(new QueryWrapper().eq("tableName", config.getTableName())); 33 | //查询列信息 34 | List columns = sysGenMapper.queryColumns(new QueryWrapper().eq("tableName", config.getTableName())); 35 | //生成代码 36 | genUtils.maker(config, table, columns); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/cloud/OSSFactory.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.cloud; 2 | 3 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 4 | import com.suke.czx.common.utils.Constant; 5 | import com.suke.czx.modules.oss.entity.SysOssSetting; 6 | import com.suke.czx.modules.oss.service.SysOssSettingService; 7 | import lombok.AllArgsConstructor; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * 文件上传Factory 12 | * 13 | * @author czx 14 | * @email object_czx@163.com 15 | * @date 2017-03-26 10:18 16 | */ 17 | @Component 18 | @AllArgsConstructor 19 | public class OSSFactory { 20 | 21 | private SysOssSettingService sysOssSettingService; 22 | 23 | public SysOssSetting getConfig() { 24 | SysOssSetting ossSetting = sysOssSettingService.getOne(Wrappers.query().lambda().eq(SysOssSetting::getStatus, 1)); 25 | if (ossSetting != null) { 26 | return ossSetting; 27 | } 28 | return new SysOssSetting(); 29 | } 30 | 31 | public ICloudStorage build() { 32 | //获取云存储配置信息 33 | return cloudStorage(getConfig()); 34 | } 35 | 36 | public ICloudStorage build(String type) { 37 | SysOssSetting config = sysOssSettingService.getOne(Wrappers.query().lambda().eq(SysOssSetting::getType, type)); 38 | return cloudStorage(config); 39 | } 40 | 41 | private ICloudStorage cloudStorage(SysOssSetting config) { 42 | if (config.getType().equals(Constant.CloudService.QINIU.getValue())) { 43 | return new QiniuCloudStorageService(config); 44 | } else if (config.getType().equals(Constant.CloudService.MINIO.getValue())) { 45 | return new MinioCloudStorageService(config); 46 | } 47 | return null; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/tenancy/service/impl/TbPlatformTenancyServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.tenancy.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import com.suke.czx.modules.tenancy.entity.TbPlatformTenancy; 8 | import com.suke.czx.modules.tenancy.mapper.TbPlatformTenancyMapper; 9 | import com.suke.czx.modules.tenancy.service.TbPlatformTenancyService; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | 14 | /** 15 | * 渠道管理 16 | * 17 | * @author czx 18 | * @email object_czx@163.com 19 | * @date 2024-11-29 14:48:31 20 | */ 21 | @Service 22 | public class TbPlatformTenancyServiceImpl extends ServiceImpl implements TbPlatformTenancyService { 23 | 24 | @Override 25 | public IPage pageList(IPage tbPlatformTenancyIPage, QueryWrapper queryWrapper) { 26 | return baseMapper.pageList(tbPlatformTenancyIPage, queryWrapper); 27 | } 28 | 29 | @Override 30 | @Transactional 31 | public void setDefault(TbPlatformTenancy tenancy) { 32 | TbPlatformTenancy tbPlatformTenancy = baseMapper.selectById(tenancy.getTenancyId()); 33 | if (tbPlatformTenancy != null) { 34 | baseMapper.update(new UpdateWrapper().set("is_default", 0)); 35 | tenancy.setIsDefault(1); 36 | baseMapper.updateById(tenancy); 37 | } 38 | } 39 | 40 | @Override 41 | public TbPlatformTenancy getDefaultTenancy() { 42 | return baseMapper.getDefaultTenancy(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/IPUtils.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import jakarta.servlet.http.HttpServletRequest; 5 | import lombok.extern.slf4j.Slf4j; 6 | 7 | /** 8 | * IP地址 9 | * 10 | * @author czx 11 | * @email object_czx@163.com 12 | * @date 2017年3月8日 下午12:57:02 13 | */ 14 | @Slf4j 15 | public class IPUtils { 16 | 17 | /** 18 | * 获取IP地址 19 | * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 20 | * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 21 | */ 22 | public static String getIpAddr(HttpServletRequest request) { 23 | String ip = null; 24 | try { 25 | ip = request.getHeader("x-forwarded-for"); 26 | if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 27 | ip = request.getHeader("Proxy-Client-IP"); 28 | } 29 | if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 30 | ip = request.getHeader("WL-Proxy-Client-IP"); 31 | } 32 | if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 33 | ip = request.getHeader("HTTP_CLIENT_IP"); 34 | } 35 | if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 36 | ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 37 | } 38 | if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 39 | ip = request.getRemoteAddr(); 40 | } 41 | } catch (Exception e) { 42 | log.error("IPUtils ERROR ", e); 43 | } 44 | 45 | // //使用代理,则获取第一个IP地址 46 | // if(StringUtils.isEmpty(ip) && ip.length() > 15) { 47 | // if(ip.indexOf(",") > 0) { 48 | // ip = ip.substring(0, ip.indexOf(",")); 49 | // } 50 | // } 51 | 52 | return ip; 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysPermission.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | import lombok.Data; 10 | 11 | import java.io.Serializable; 12 | import java.util.List; 13 | 14 | 15 | /** 16 | * 接口权限管理 17 | * 18 | * @author czx 19 | * @email object_czx@163.com 20 | * @date 2023-05-17 14:48:21 21 | */ 22 | @Data 23 | @TableName("sys_permission") 24 | public class SysPermission implements Serializable { 25 | public static final long serialVersionUID = 1L; 26 | 27 | @TableId(type = IdType.INPUT) 28 | @Schema(description = "权限ID") 29 | @JsonProperty(value = "permissionId") 30 | public String permissionId; 31 | 32 | @Schema(description = "删除状态 0未删除,1已删除") 33 | @JsonProperty(value = "deleteStatus") 34 | public Integer deleteStatus; 35 | 36 | @Schema(description = "英文名称") 37 | @JsonProperty(value = "englishName") 38 | public String englishName; 39 | 40 | @Schema(description = "模块名称") 41 | @JsonProperty(value = "moduleName") 42 | public String moduleName; 43 | 44 | @Schema(description = "权限名称") 45 | @JsonProperty(value = "name") 46 | public String name; 47 | 48 | @Schema(description = "URL") 49 | @JsonProperty(value = "url") 50 | public String url; 51 | 52 | @Schema(description = "菜单ID") 53 | @JsonProperty(value = "menuId") 54 | public String menuId; 55 | 56 | @TableField(exist = false) 57 | @Schema(description = "菜单ID") 58 | @JsonProperty(value = "menuName") 59 | public String menuName; 60 | 61 | @TableField(exist = false) 62 | public List children; 63 | 64 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/entity/SysUser.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonFormat; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | import lombok.Data; 10 | 11 | import java.io.Serializable; 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | /** 16 | * 系统用户 17 | * 18 | * @author czx 19 | * @email object_czx@163.com 20 | */ 21 | @Data 22 | @TableName("sys_user") 23 | @Schema(description = "系统用户") 24 | public class SysUser implements Serializable { 25 | 26 | public static final long serialVersionUID = 1L; 27 | 28 | @TableId(value = "user_id", type = IdType.ASSIGN_UUID) 29 | public String userId; 30 | 31 | @Schema(description = "用户名") 32 | public String username; 33 | 34 | @Schema(description = "姓名") 35 | public String name; 36 | 37 | @Schema(description = "密码") 38 | public String password; 39 | 40 | @Schema(description = "邮箱") 41 | public String email; 42 | 43 | @Schema(description = "手机号") 44 | public String mobile; 45 | 46 | @Schema(description = "头像") 47 | public String photo; 48 | 49 | @Schema(description = "状态 0:禁用 1:正常") 50 | public Integer status; 51 | 52 | @Schema(description = "审核状态 0:拒绝 1:审核中,2:通过") 53 | public Integer auditStatus; 54 | 55 | @Schema(description = "创建者ID") 56 | public String createUserId; 57 | 58 | @Schema(description = "租户ID") 59 | public Integer tenancyId; 60 | 61 | @Schema(description = "创建时间") 62 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 63 | public Date createTime; 64 | 65 | @TableField(exist = false) 66 | @Schema(description = "角色ID") 67 | public List roleIdList; 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/MPPageConvert.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | import cn.hutool.core.map.MapUtil; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @Author czx 13 | * @Description Page 数据转换 14 | * @Date 17:13 2019/4/18 15 | **/ 16 | @Component 17 | public class MPPageConvert { 18 | 19 | public String getKeyword(Map param){ 20 | return MapUtil.getStr(param, "keyword"); 21 | } 22 | 23 | /** 24 | * @Author czx 25 | * @Description 前台传过来的参数转换为MyBatis Plus的Page 26 | * @Date 17:14 2019/4/18 27 | * @Param [param] 28 | * @return com.baomidou.mybatisplus.core.metadata.IPage 29 | **/ 30 | public IPage pageParamConvert(Map param){ 31 | int currPage = 1; 32 | int limit = 10; 33 | if(MapUtil.getInt(param,"current") != null){ 34 | currPage = MapUtil.getInt(param,"current"); 35 | } 36 | if(MapUtil.getInt(param,"limit") != null){ 37 | limit = MapUtil.getInt(param,"limit"); 38 | } 39 | return new Page<>(currPage,limit); 40 | } 41 | 42 | /** 43 | * @Author czx 44 | * @Description 将MyBatis Plus 的Page 转换为前台能用的Page 45 | * @Date 17:14 2019/4/18 46 | * @Param [page] 47 | * @return java.util.HashMap 48 | **/ 49 | public HashMap pageValueConvert(IPage page){ 50 | HashMap pageData = new HashMap<>(); 51 | pageData.put("list",page.getRecords()); 52 | pageData.put("totalCount",page.getTotal()); 53 | pageData.put("limit",page.getSize()); 54 | pageData.put("current",page.getCurrent()); 55 | pageData.put("totalPage",page.getPages()); 56 | return pageData; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/gen/controller/SysGenController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.gen.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.suke.czx.common.base.AbstractController; 7 | import com.suke.czx.modules.gen.entity.InfoRmationSchema; 8 | import com.suke.czx.modules.gen.entity.MakerConfigEntity; 9 | import com.suke.czx.modules.gen.service.SysGenService; 10 | import com.suke.czx.common.utils.R; 11 | import io.swagger.v3.oas.annotations.tags.Tag; 12 | import lombok.AllArgsConstructor; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.Map; 16 | 17 | @RestController 18 | @RequestMapping("/sys/gen") 19 | @AllArgsConstructor 20 | @Tag(name = "SysGenController", description = "代码生成") 21 | public class SysGenController extends AbstractController { 22 | 23 | private final SysGenService sysGenService; 24 | 25 | /** 26 | * 列表 27 | */ 28 | @GetMapping(value = "/list") 29 | public R list(@RequestParam Map params) { 30 | //查询列表数据 31 | QueryWrapper queryWrapper = new QueryWrapper<>(); 32 | final String keyword = mpPageConvert.getKeyword(params); 33 | if (StrUtil.isNotEmpty(keyword)) { 34 | queryWrapper 35 | .lambda() 36 | .like(InfoRmationSchema::getTableName, keyword); 37 | } 38 | IPage pageList = sysGenService.queryTableList(mpPageConvert.pageParamConvert(params), queryWrapper); 39 | return R.ok().setData(pageList); 40 | } 41 | 42 | /** 43 | * 生成代码 44 | * 45 | * @param makerConfigEntity 46 | */ 47 | @PostMapping(value = "/create") 48 | public R create(@RequestBody MakerConfigEntity makerConfigEntity) { 49 | sysGenService.generatorCode(makerConfigEntity); 50 | return R.ok(); 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/cloud/ICloudStorage.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.cloud; 2 | 3 | import cn.hutool.core.date.DateUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import org.springframework.web.multipart.MultipartFile; 6 | 7 | import java.io.InputStream; 8 | import java.util.UUID; 9 | 10 | public interface ICloudStorage { 11 | 12 | default String newFileName() { 13 | return UUID.randomUUID().toString().replaceAll("-", ""); 14 | } 15 | 16 | default String newFileName(String suffix) { 17 | return UUID.randomUUID().toString().replaceAll("-", "") + "." + suffix; 18 | } 19 | 20 | /** 21 | * 文件路径 22 | * 23 | * @param prefix 前缀 24 | * @param suffix 后缀 25 | * @return 返回上传路径 26 | */ 27 | default String getPath(String prefix, String suffix) { 28 | 29 | //文件路径 30 | String path = DateUtil.today() + "/" + newFileName(); 31 | 32 | if (StrUtil.isNotBlank(prefix)) { 33 | path = prefix + "/" + path; 34 | } 35 | 36 | return path + suffix; 37 | } 38 | 39 | /** 40 | * 文件上传 41 | */ 42 | String upload(MultipartFile file, String objectName); 43 | 44 | /** 45 | * 文件上传 46 | * 47 | * @param data 文件字节数组 48 | * @param path 文件路径,包含文件名 49 | * @return 返回http地址 50 | */ 51 | String upload(byte[] data, String path); 52 | 53 | /** 54 | * 文件上传 55 | * 56 | * @param data 文件字节数组 57 | * @param suffix 后缀 58 | * @return 返回http地址 59 | */ 60 | String uploadSuffix(byte[] data, String suffix); 61 | 62 | /** 63 | * 文件上传 64 | * 65 | * @param inputStream 字节流 66 | * @param path 文件路径,包含文件名 67 | * @return 返回http地址 68 | */ 69 | String upload(InputStream inputStream, String path); 70 | 71 | /** 72 | * 文件上传 73 | * 74 | * @param inputStream 字节流 75 | * @param suffix 后缀 76 | * @return 返回http地址 77 | */ 78 | String uploadSuffix(InputStream inputStream, String suffix); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/annotation/ApplicationAuthAspect.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.annotation; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 5 | import com.suke.czx.common.exception.RRException; 6 | import com.suke.czx.common.utils.HttpContextUtils; 7 | import com.suke.czx.modules.application.entity.XApplication; 8 | import com.suke.czx.modules.application.service.XApplicationService; 9 | import jakarta.annotation.Resource; 10 | import jakarta.servlet.http.HttpServletRequest; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.aspectj.lang.JoinPoint; 13 | import org.aspectj.lang.annotation.After; 14 | import org.aspectj.lang.annotation.Aspect; 15 | import org.aspectj.lang.annotation.Before; 16 | import org.aspectj.lang.annotation.Pointcut; 17 | import org.springframework.stereotype.Component; 18 | 19 | /** 20 | * 验证app的appKey和appSecret 21 | */ 22 | @Slf4j 23 | @Aspect 24 | @Component 25 | public class ApplicationAuthAspect { 26 | 27 | @Resource 28 | public XApplicationService xApplicationService; 29 | 30 | @Pointcut("@annotation(com.suke.czx.modules.application.annotation.ApplicationAuth)") 31 | public void queryMethod() { 32 | } 33 | 34 | 35 | @Before("queryMethod()") 36 | public void beforeAdvice(JoinPoint joinPoint) { 37 | // 获取方法名称和参数 38 | HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); 39 | String appKey = request.getHeader("appKey"); 40 | String appSecret = request.getHeader("appSecret"); 41 | if (StrUtil.isEmpty(appKey) || StrUtil.isEmpty(appSecret)) { 42 | throw new RRException("认证错误"); 43 | } 44 | XApplication application = xApplicationService.getOne(Wrappers.lambdaQuery().eq(XApplication::getAppKey, appKey).eq(XApplication::getAppSecret, appSecret).last("limit 1")); 45 | if (application == null) { 46 | throw new RRException("认证错误"); 47 | } 48 | } 49 | 50 | 51 | @After("queryMethod()") 52 | public void afterAdvice(JoinPoint joinPoint) { 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/SpringContextUtils.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.context.ApplicationEvent; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.lang.annotation.Annotation; 10 | import java.util.Map; 11 | 12 | /** 13 | * Spring Context 工具类 14 | * 15 | * @author czx 16 | * @email object_czx@163.com 17 | * @date 2016年11月29日 下午11:45:51 18 | */ 19 | @Component 20 | public class SpringContextUtils implements ApplicationContextAware { 21 | public static ApplicationContext applicationContext; 22 | 23 | @Override 24 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 25 | SpringContextUtils.applicationContext = applicationContext; 26 | } 27 | 28 | public static void publishEvent(ApplicationEvent event) { 29 | if (applicationContext == null) { 30 | return; 31 | } 32 | applicationContext.publishEvent(event); 33 | } 34 | 35 | public static Map getAnnotation(Class annotationType) { 36 | return applicationContext.getBeansWithAnnotation(annotationType); 37 | } 38 | 39 | 40 | public static Object getBean(String name) { 41 | return applicationContext.getBean(name); 42 | } 43 | 44 | public static T getBean(Class requiredType) { 45 | return applicationContext.getBean(requiredType); 46 | } 47 | 48 | public static T getBean(String name, Class requiredType) { 49 | return applicationContext.getBean(name, requiredType); 50 | } 51 | 52 | public static boolean containsBean(String name) { 53 | return applicationContext.containsBean(name); 54 | } 55 | 56 | public static boolean isSingleton(String name) { 57 | return applicationContext.isSingleton(name); 58 | } 59 | 60 | public static Class getType(String name) { 61 | return applicationContext.getType(name); 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/entity/SysOssSetting.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import com.fasterxml.jackson.annotation.JsonFormat; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 9 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 10 | import io.swagger.v3.oas.annotations.media.Schema; 11 | import lombok.Data; 12 | 13 | import java.io.Serializable; 14 | import java.util.Date; 15 | 16 | /** 17 | * 文件上传配置 18 | * 19 | * @author czx 20 | * @email object_czx@163.com 21 | * @date 2024-12-02 09:34:46 22 | */ 23 | @Data 24 | @TableName("sys_oss_setting") 25 | public class SysOssSetting implements Serializable { 26 | public static final long serialVersionUID = 1L; 27 | 28 | @TableId(type = IdType.AUTO) 29 | @Schema(description = "id") 30 | @JsonProperty(value = "id") 31 | @JsonSerialize(using = ToStringSerializer.class) 32 | public Long id; 33 | 34 | @Schema(description = "URL地址") 35 | @JsonProperty(value = "url") 36 | public String url; 37 | 38 | @Schema(description = "类型") 39 | @JsonProperty(value = "type") 40 | public String type; 41 | 42 | @Schema(description = "访问密钥") 43 | @JsonProperty(value = "accessKey") 44 | public String accessKey; 45 | 46 | @Schema(description = "密钥") 47 | @JsonProperty(value = "secretKey") 48 | public String secretKey; 49 | 50 | @Schema(description = "桶名称") 51 | @JsonProperty(value = "bucketName") 52 | public String bucketName; 53 | 54 | @Schema(description = "view") 55 | @JsonProperty(value = "view") 56 | public String view; 57 | 58 | @Schema(description = "前缀") 59 | @JsonProperty(value = "prefix") 60 | public String prefix; 61 | 62 | @Schema(description = "创建时间") 63 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 64 | @JsonProperty(value = "createDate") 65 | public Date createDate; 66 | 67 | @Schema(description = "1:默认 0可选") 68 | @JsonProperty(value = "status") 69 | public Integer status; 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/handler/CustomAuthenticationFailHandler.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.handler; 2 | 3 | import cn.hutool.core.util.CharsetUtil; 4 | import cn.hutool.json.JSONUtil; 5 | import com.suke.czx.common.event.LoginLogEvent; 6 | import com.suke.czx.common.utils.IPUtils; 7 | import com.suke.czx.common.utils.R; 8 | import com.suke.czx.common.utils.SpringContextUtils; 9 | import com.suke.czx.modules.sys.entity.SysLoginLog; 10 | import jakarta.servlet.http.HttpServletRequest; 11 | import jakarta.servlet.http.HttpServletResponse; 12 | import lombok.SneakyThrows; 13 | import lombok.extern.slf4j.Slf4j; 14 | import org.springframework.http.MediaType; 15 | import org.springframework.security.authentication.DisabledException; 16 | import org.springframework.security.core.AuthenticationException; 17 | import org.springframework.security.web.authentication.AuthenticationFailureHandler; 18 | import org.springframework.stereotype.Component; 19 | 20 | import java.io.PrintWriter; 21 | 22 | /** 23 | * @Description 24 | * @Date 21:05 25 | * @Author yzcheng90@qq.com 26 | **/ 27 | @Slf4j 28 | @Component 29 | public class CustomAuthenticationFailHandler implements AuthenticationFailureHandler { 30 | 31 | @SneakyThrows 32 | @Override 33 | public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception){ 34 | 35 | final String username = request.getParameter("username"); 36 | SysLoginLog loginLog = new SysLoginLog(); 37 | loginLog.setOptionIp(IPUtils.getIpAddr(request)); 38 | loginLog.setOptionName("用户登录失败"); 39 | loginLog.setOptionTerminal(request.getHeader("User-Agent")); 40 | loginLog.setUsername(username); 41 | SpringContextUtils.publishEvent(new LoginLogEvent(loginLog)); 42 | 43 | response.setCharacterEncoding(CharsetUtil.UTF_8); 44 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 45 | PrintWriter printWriter = response.getWriter(); 46 | 47 | if(exception instanceof DisabledException){ 48 | printWriter.append(JSONUtil.toJsonStr(R.error("账户被禁用,请联系管理员"))); 49 | }else { 50 | printWriter.append(JSONUtil.toJsonStr(R.error(exception.getMessage()))); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/handler/CustomLogoutSuccessHandler.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.handler; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import com.suke.czx.common.event.LoginLogEvent; 5 | import com.suke.czx.common.utils.Constant; 6 | import com.suke.czx.common.utils.IPUtils; 7 | import com.suke.czx.common.utils.SpringContextUtils; 8 | import com.suke.czx.modules.sys.entity.SysLoginLog; 9 | import jakarta.annotation.Resource; 10 | import jakarta.servlet.ServletException; 11 | import jakarta.servlet.http.HttpServletRequest; 12 | import jakarta.servlet.http.HttpServletResponse; 13 | import lombok.extern.slf4j.Slf4j; 14 | import org.springframework.data.redis.core.RedisTemplate; 15 | import org.springframework.security.core.Authentication; 16 | import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; 17 | import org.springframework.stereotype.Component; 18 | 19 | import java.io.IOException; 20 | import java.util.Date; 21 | 22 | /** 23 | * @author czx 24 | * @projectName x-springboot 25 | * @description: 自定义退出成功处理器 26 | * @date 2019/12/2415:12 27 | */ 28 | @Slf4j 29 | @Component 30 | public class CustomLogoutSuccessHandler implements LogoutSuccessHandler { 31 | 32 | @Resource 33 | private RedisTemplate redisTemplate; 34 | 35 | @Override 36 | public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 37 | String token = request.getHeader(Constant.TOKEN); 38 | Object userInfo = redisTemplate.opsForValue().get(Constant.AUTHENTICATION_TOKEN + token); 39 | if (ObjectUtil.isNotNull(userInfo)) { 40 | String[] user = userInfo.toString().split(","); 41 | if (user.length == 2) { 42 | SysLoginLog loginLog = new SysLoginLog(); 43 | loginLog.setOptionIp(IPUtils.getIpAddr(request)); 44 | loginLog.setOptionName("用户退出成功"); 45 | loginLog.setOptionTerminal(request.getHeader("User-Agent")); 46 | loginLog.setUsername(user[1]); 47 | loginLog.setOptionTime(new Date()); 48 | SpringContextUtils.publishEvent(new LoginLogEvent(loginLog)); 49 | } 50 | } 51 | redisTemplate.delete(Constant.AUTHENTICATION_TOKEN + token); 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/tenancy/entity/TbPlatformTenancy.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.tenancy.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import com.fasterxml.jackson.annotation.JsonFormat; 5 | import com.fasterxml.jackson.annotation.JsonProperty; 6 | import io.swagger.v3.oas.annotations.media.Schema; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | import java.util.Date; 11 | 12 | 13 | /** 14 | * 渠道管理 15 | * 16 | * @author czx 17 | * @email object_czx@163.com 18 | * @date 2024-11-29 14:48:31 19 | */ 20 | @Data 21 | @TableName("tb_platform_tenancy") 22 | public class TbPlatformTenancy implements Serializable { 23 | public static final long serialVersionUID = 1L; 24 | 25 | @TableId(type = IdType.AUTO) 26 | @Schema(description = "渠道ID") 27 | @JsonProperty(value = "tenancyId") 28 | public Integer tenancyId; 29 | 30 | @Schema(description = "渠道名称") 31 | @JsonProperty(value = "tenancyName") 32 | public String tenancyName; 33 | 34 | @Schema(description = "渠道备注") 35 | @JsonProperty(value = "tenancyRemark") 36 | public String tenancyRemark; 37 | 38 | @Schema(description = "折扣") 39 | @JsonProperty(value = "discount") 40 | public Double discount; 41 | 42 | @Schema(description = "是否默认租户") 43 | @JsonProperty(value = "isDefault") 44 | public Integer isDefault; 45 | 46 | @Schema(description = "广告位配置") 47 | @JsonProperty(value = "ex") 48 | public String ex; 49 | 50 | @TableLogic 51 | @Schema(description = "是否删除") 52 | @JsonProperty(value = "isDelete") 53 | public Integer isDelete; 54 | 55 | @Schema(description = "是否更新数据(1:是,0:否)") 56 | @JsonProperty(value = "updateData") 57 | public Integer updateData; 58 | 59 | @Schema(description = "创建人ID") 60 | @JsonProperty(value = "userId") 61 | public String userId; 62 | 63 | @Schema(description = "创建时间") 64 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 65 | @JsonProperty(value = "createTime") 66 | public Date createTime; 67 | 68 | @Schema(description = "父级租户ID") 69 | @JsonProperty(value = "tenancyPid") 70 | public Integer tenancyPid; 71 | 72 | @TableField(exist = false) 73 | @Schema(description = "父级租户名称") 74 | @JsonProperty(value = "tenancyParentName") 75 | public String tenancyParentName; 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/utils/Constant.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.utils; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * 常量 7 | * 8 | * @author czx 9 | * @email object_czx@163.com 10 | * @date 2016年11月15日 下午1:23:52 11 | */ 12 | public class Constant { 13 | 14 | public static final String SYSTEM_NAME = "x-springboot:"; 15 | public static final String SYSTEM_CACHE = "x-springboot:default-cache:"; 16 | public static final String NUMBER_CODE_KEY = SYSTEM_NAME + "number:code:"; 17 | public static final String MOBILE_CODE_KEY = SYSTEM_NAME + "mobile:code:"; 18 | public static final String AUTHENTICATION_TOKEN = SYSTEM_NAME + "token:"; 19 | 20 | public static final String TOKEN = "token"; 21 | public static final String TOKEN_ENTRY_POINT_URL = "/token/login"; 22 | public static final String TOKEN_LOGOUT_URL = "/token/logout"; 23 | public static final int TOKEN_EXPIRE = 60 * 60 * 24 * 7; 24 | 25 | /** 26 | * 超级管理员ID 27 | */ 28 | public static final String SUPER_ADMIN = "0"; 29 | public static final String SUPER_MINI_ADMIN = "1"; 30 | 31 | public static final int CODE_SIZE = 4; 32 | 33 | /** 34 | * 菜单类型 35 | * 36 | * @author czx 37 | * @email object_czx@163.com 38 | * @date 2016年11月15日 下午1:24:29 39 | */ 40 | public enum MenuType { 41 | /** 42 | * 目录 43 | */ 44 | CATALOG(0), 45 | /** 46 | * 菜单 47 | */ 48 | MENU(1), 49 | /** 50 | * 按钮 51 | */ 52 | BUTTON(2); 53 | 54 | private int value; 55 | 56 | MenuType(int value) { 57 | this.value = value; 58 | } 59 | 60 | public int getValue() { 61 | return value; 62 | } 63 | } 64 | 65 | /** 66 | * 云服务商 67 | */ 68 | @Getter 69 | public enum CloudService { 70 | /** 71 | * 七牛云 72 | */ 73 | QINIU("qiniu"), 74 | /** 75 | * 阿里云 76 | */ 77 | ALIYUN("aliyun"), 78 | /** 79 | * 腾讯云 80 | */ 81 | QCLOUD("qcloud"), 82 | /** 83 | * minio 84 | */ 85 | MINIO("minio"); 86 | 87 | private final String value; 88 | 89 | CloudService(String value) { 90 | this.value = value; 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/component/AliyunNewSendMessageComponent.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.component; 2 | 3 | import cn.hutool.core.net.URLEncodeUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import cn.hutool.http.HttpResponse; 6 | import cn.hutool.http.HttpUtil; 7 | import cn.hutool.json.JSONObject; 8 | import cn.hutool.json.JSONUtil; 9 | import com.suke.czx.modules.msg.component.entity.MessageBody; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author czx 18 | * @title: SendMessageComponent 19 | * @projectName task-manage 20 | * @description: https://market.aliyun.com/apimarket/detail/cmapi029993 21 | * @date 2023/1/2917:08 22 | */ 23 | @Slf4j 24 | @Component 25 | public class AliyunNewSendMessageComponent extends SendMessageAbstract { 26 | 27 | @Override 28 | public boolean sendMessage(MessageBody messageBody) { 29 | String url = messageBody.getServiceUrl(); 30 | String mobile = messageBody.getMobile(); 31 | String code = messageBody.getCode(); 32 | String appCode = messageBody.getAppCode(); 33 | String message = messageBody.getTemplate().replaceAll("#code", code); 34 | 35 | String host = url + "?mobile=" + mobile + "&content=" + URLEncodeUtil.encode(message); 36 | Map headers = new HashMap<>(); 37 | //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105 38 | headers.put("Authorization", "APPCODE " + appCode); 39 | try { 40 | HttpResponse response = HttpUtil 41 | .createPost(host) 42 | .headerMap(headers, true) 43 | .execute(); 44 | String body = response.body(); 45 | JSONObject entries = JSONUtil.parseObj(body); 46 | String returnStatus = entries.getStr("ReturnStatus"); 47 | if (StrUtil.isEmpty(returnStatus) || returnStatus.equals("Faild")) { 48 | this.sendMessageFail(messageBody, entries.getStr("Message")); 49 | } else { 50 | log.info("短信发送成功:{},任务ID:{}", message, entries.getStr("TaskID")); 51 | return true; 52 | } 53 | } catch (Exception e) { 54 | this.sendMessageFail(messageBody, e.getMessage()); 55 | } 56 | return false; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/param/entity/TbParam.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.param.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonFormat; 8 | import com.fasterxml.jackson.annotation.JsonProperty; 9 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 10 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 11 | import io.swagger.v3.oas.annotations.media.Schema; 12 | import lombok.Data; 13 | 14 | import java.io.Serializable; 15 | import java.util.Date; 16 | 17 | 18 | /** 19 | * 参数管理 20 | * 21 | * @author czx 22 | * @email object_czx@163.com 23 | * @date 2023-04-03 09:19:41 24 | */ 25 | @Data 26 | @TableName("sys_param") 27 | public class TbParam implements Serializable { 28 | public static final long serialVersionUID = 1L; 29 | 30 | @TableId(type = IdType.ASSIGN_UUID) 31 | @Schema(description = "参数ID") 32 | @JsonProperty(value = "paramId") 33 | @JsonSerialize(using = ToStringSerializer.class) 34 | public String paramId; 35 | 36 | @Schema(description = "参数名称") 37 | @JsonProperty(value = "paramName") 38 | public String paramName; 39 | 40 | @Schema(description = "参数类型") 41 | @JsonProperty(value = "paramType") 42 | public String paramType; 43 | 44 | @Schema(description = "租户ID") 45 | @JsonProperty(value = "tenancyId") 46 | @JsonSerialize(using = ToStringSerializer.class) 47 | public Long tenancyId; 48 | 49 | @TableField(exist = false) 50 | @Schema(description = "租户名称") 51 | @JsonProperty(value = "tenancyName") 52 | public String tenancyName; 53 | 54 | @Schema(description = "参数描述") 55 | @JsonProperty(value = "paramDescribe") 56 | public String paramDescribe; 57 | 58 | @Schema(description = "参数KEY") 59 | @JsonProperty(value = "paramKey") 60 | public String paramKey; 61 | 62 | @Schema(description = "参数VALUE") 63 | @JsonProperty(value = "paramValue") 64 | public String paramValue; 65 | 66 | @Schema(description = "创建时间") 67 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 68 | @JsonProperty(value = "createTime") 69 | public Date createTime; 70 | 71 | @Schema(description = "修改时间") 72 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 73 | @JsonProperty(value = "updateTime") 74 | public Date updateTime; 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/controller/SysOssController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.controller; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.suke.czx.common.base.AbstractController; 6 | import com.suke.czx.common.exception.RRException; 7 | import com.suke.czx.common.utils.R; 8 | import com.suke.czx.modules.oss.entity.SysOss; 9 | import com.suke.czx.modules.oss.service.SysOssService; 10 | import io.swagger.v3.oas.annotations.tags.Tag; 11 | import lombok.AllArgsConstructor; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.web.bind.annotation.*; 14 | import org.springframework.web.multipart.MultipartFile; 15 | 16 | import java.util.Arrays; 17 | import java.util.Date; 18 | import java.util.Map; 19 | 20 | /** 21 | * 文件上传 22 | * 23 | * @author czx 24 | * @email object_czx@163.com 25 | * @date 2017-03-25 12:13:26 26 | */ 27 | @Slf4j 28 | @RestController 29 | @RequestMapping("sys/oss") 30 | @AllArgsConstructor 31 | @Tag(name = "SysOssController", description = "文件上传") 32 | public class SysOssController extends AbstractController { 33 | 34 | private final SysOssService sysOssService; 35 | 36 | /** 37 | * 列表 38 | */ 39 | @GetMapping(value = "/list") 40 | public R list(@RequestParam Map params) { 41 | //查询列表数据 42 | QueryWrapper queryWrapper = new QueryWrapper<>(); 43 | IPage pageList = sysOssService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 44 | return R.ok().setData(pageList); 45 | } 46 | 47 | /** 48 | * 上传文件 49 | */ 50 | @PostMapping(value = "/upload") 51 | public R upload(@RequestParam("file") MultipartFile file) throws Exception { 52 | if (file.isEmpty()) { 53 | throw new RRException("上传文件不能为空"); 54 | } 55 | 56 | //上传文件 57 | String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); 58 | String url = ""; 59 | 60 | //保存文件信息 61 | SysOss ossEntity = new SysOss(); 62 | ossEntity.setUrl(url); 63 | ossEntity.setCreateDate(new Date()); 64 | sysOssService.save(ossEntity); 65 | 66 | return R.ok().put("url", url); 67 | } 68 | 69 | 70 | /** 71 | * 删除 72 | */ 73 | @PostMapping(value = "/delete") 74 | public R delete(@RequestBody Long[] ids) { 75 | sysOssService.removeByIds(Arrays.asList(ids)); 76 | return R.ok(); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/exception/RRExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.exception; 2 | 3 | import com.suke.czx.common.utils.HttpContextUtils; 4 | import com.suke.czx.common.utils.R; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.dao.DuplicateKeyException; 7 | import org.springframework.http.converter.HttpMessageNotReadableException; 8 | import org.springframework.jdbc.BadSqlGrammarException; 9 | import org.springframework.web.bind.MethodArgumentNotValidException; 10 | import org.springframework.web.bind.annotation.ExceptionHandler; 11 | import org.springframework.web.bind.annotation.RestControllerAdvice; 12 | import org.springframework.web.servlet.resource.NoResourceFoundException; 13 | 14 | 15 | /** 16 | * 异常处理器 17 | * 18 | * @author czx 19 | * @email object_czx@163.com 20 | * @date 2016年10月27日 下午10:16:19 21 | */ 22 | @Slf4j 23 | @RestControllerAdvice 24 | public class RRExceptionHandler extends R { 25 | /** 26 | * 自定义异常 27 | */ 28 | @ExceptionHandler(RRException.class) 29 | public R handleRRException(RRException e) { 30 | return R.error(e.getCode(), e.getMessage()); 31 | } 32 | 33 | @ExceptionHandler(DuplicateKeyException.class) 34 | public R handleDuplicateKeyException(DuplicateKeyException e) { 35 | return R.error("数据库中已存在该记录"); 36 | } 37 | 38 | @ExceptionHandler(MethodArgumentNotValidException.class) 39 | public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { 40 | log.error("参数错误:", e); 41 | return R.error("参数错误"); 42 | } 43 | 44 | @ExceptionHandler(HttpMessageNotReadableException.class) 45 | public R handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { 46 | log.error("参数JSON解析错误:", e); 47 | return R.error("参数JSON解析错误"); 48 | } 49 | 50 | @ExceptionHandler(NoResourceFoundException.class) 51 | public R handleHttpMessageNotReadableException(NoResourceFoundException e) { 52 | log.error("无该资源:", e); 53 | return R.error("无该资源"); 54 | } 55 | 56 | @ExceptionHandler(BadSqlGrammarException.class) 57 | public R handleBadSqlGrammarException(BadSqlGrammarException e) { 58 | String contextPath = HttpContextUtils.getHttpServletRequest().getRequestURI(); 59 | log.error("contextPath:{},SQL语法错误:{}", contextPath, e.getMessage()); 60 | return R.error("SQL语法错误"); 61 | } 62 | 63 | @ExceptionHandler(Exception.class) 64 | public R handleException(Exception e) { 65 | log.error("发生异常", e); 66 | return R.error(e.getMessage()); 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/entity/XMessageService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.suke.czx.modules.tenancy.entity.TenancyBase; 9 | import io.swagger.v3.oas.annotations.media.Schema; 10 | import lombok.Data; 11 | import lombok.EqualsAndHashCode; 12 | 13 | import java.io.Serializable; 14 | 15 | 16 | /** 17 | * 短信服务 18 | * 19 | * @author czx 20 | * @email object_czx@163.com 21 | * @date 2025-08-15 17:51:27 22 | */ 23 | @Data 24 | @EqualsAndHashCode(callSuper = true) 25 | @TableName("x_message_service") 26 | public class XMessageService extends TenancyBase implements Serializable { 27 | 28 | public static final long serialVersionUID = 1L; 29 | 30 | @TableId(type = IdType.AUTO) 31 | @Schema(description = "服务ID") 32 | @JsonProperty(value = "serviceId") 33 | public Integer serviceId; 34 | 35 | @Schema(description = "AppCode") 36 | @JsonProperty(value = "appCode") 37 | public String appCode; 38 | 39 | @Schema(description = "应用ID") 40 | @JsonProperty(value = "appId") 41 | public Integer appId; 42 | 43 | @Schema(description = "AppKey") 44 | @JsonProperty(value = "appKey") 45 | public String appKey; 46 | 47 | @Schema(description = "AppSecret") 48 | @JsonProperty(value = "appSecret") 49 | public String appSecret; 50 | 51 | @Schema(description = "默认模板") 52 | @JsonProperty(value = "defaultTemplate") 53 | public String defaultTemplate; 54 | 55 | @Schema(description = "是否使用(1使用,0未使用)") 56 | @JsonProperty(value = "isEnable") 57 | public Integer isEnable; 58 | 59 | @Schema(description = "同租户下只能有一个默认服务(1是,0否)") 60 | @JsonProperty(value = "isDefault") 61 | public Integer isDefault; 62 | 63 | @Schema(description = "产品ID") 64 | @JsonProperty(value = "productId") 65 | public String productId; 66 | 67 | @Schema(description = "服务实现类地址") 68 | @JsonProperty(value = "serviceClass") 69 | public String serviceClass; 70 | 71 | @Schema(description = "服务名称") 72 | @JsonProperty(value = "serviceName") 73 | public String serviceName; 74 | 75 | @Schema(description = "接口URL") 76 | @JsonProperty(value = "serviceUrl") 77 | public String serviceUrl; 78 | /** 79 | * 选择的模板 80 | */ 81 | @TableField(exist = false) 82 | public Integer[] templateIds; 83 | 84 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/lock/NotDoubleSubmitAOP.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.lock; 2 | 3 | import cn.hutool.core.text.CharSequenceUtil; 4 | import com.suke.czx.common.utils.Constant; 5 | import com.suke.czx.common.utils.HttpContextUtils; 6 | import com.suke.czx.common.utils.R; 7 | import jakarta.annotation.Resource; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.aspectj.lang.ProceedingJoinPoint; 10 | import org.aspectj.lang.Signature; 11 | import org.aspectj.lang.annotation.Around; 12 | import org.aspectj.lang.annotation.Aspect; 13 | import org.aspectj.lang.reflect.MethodSignature; 14 | import org.springframework.stereotype.Component; 15 | import org.springframework.util.DigestUtils; 16 | 17 | import java.lang.reflect.Method; 18 | import java.nio.charset.Charset; 19 | import java.util.UUID; 20 | import java.util.concurrent.TimeUnit; 21 | 22 | /** 23 | * 防重复提交注解的实现,使用AOP。 24 | */ 25 | @Slf4j 26 | @Aspect 27 | @Component 28 | public class NotDoubleSubmitAOP { 29 | 30 | @Resource 31 | private RedissonLock redissonLock; 32 | 33 | @Around("execution(public * *(..)) && @annotation(NotDoubleSubmit)") 34 | public Object interceptor(ProceedingJoinPoint pjp) throws Throwable { 35 | // 获取到这个注解 36 | MethodSignature signature = (MethodSignature) pjp.getSignature(); 37 | Method method = signature.getMethod(); 38 | NotDoubleSubmit notDoubleSubmit = method.getAnnotation(NotDoubleSubmit.class); 39 | 40 | /* 41 | * 锁 key 42 | */ 43 | String token = HttpContextUtils.getHttpServletRequest().getHeader("token"); 44 | final String lockKey = Constant.SYSTEM_NAME + generateKey(pjp, CharSequenceUtil.isEmpty(token) ? UUID.randomUUID().toString() : token); 45 | 46 | // 上锁 47 | final boolean success = redissonLock.lock(lockKey, notDoubleSubmit.delaySeconds(), TimeUnit.SECONDS); 48 | if (!success) { 49 | // 这里也可以改为自己项目自定义的异常抛出 50 | return R.error("操作太频繁"); 51 | } 52 | return pjp.proceed(); 53 | } 54 | 55 | private String generateKey(ProceedingJoinPoint pjp, String token) { 56 | StringBuilder sb = new StringBuilder(); 57 | Signature signature = pjp.getSignature(); 58 | MethodSignature methodSignature = (MethodSignature) signature; 59 | Method method = methodSignature.getMethod(); 60 | sb.append(token); 61 | sb.append(pjp.getTarget().getClass().getName()).append(method.getName());//方法名 62 | for (Object o : pjp.getArgs()) { 63 | sb.append(o.toString()); 64 | } 65 | return DigestUtils.md5DigestAsHex(sb.toString().getBytes(Charset.defaultCharset())); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/shardingtable/ShardingQueryDataAspect.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.shardingtable; 2 | 3 | import cn.hutool.core.map.MapUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.suke.czx.common.exception.RRException; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.aspectj.lang.JoinPoint; 8 | import org.aspectj.lang.annotation.After; 9 | import org.aspectj.lang.annotation.Aspect; 10 | import org.aspectj.lang.annotation.Before; 11 | import org.aspectj.lang.annotation.Pointcut; 12 | import org.aspectj.lang.reflect.MethodSignature; 13 | import org.springframework.stereotype.Component; 14 | 15 | import java.lang.reflect.Method; 16 | import java.util.Map; 17 | 18 | /** 19 | * 分表查询 20 | */ 21 | @Slf4j 22 | @Aspect 23 | @Component 24 | public class ShardingQueryDataAspect { 25 | 26 | 27 | @Pointcut("@annotation(com.suke.czx.common.shardingtable.ShardingQueryData)") 28 | public void queryMethod() { 29 | } 30 | 31 | /** 32 | * 设置分表 33 | * 34 | * @param joinPoint 35 | */ 36 | @Before("queryMethod()") 37 | public void beforeAdvice(JoinPoint joinPoint) { 38 | // 获取方法名称和参数 39 | Object[] args = joinPoint.getArgs(); 40 | if (args != null && args.length > 0) { 41 | Object arg = args[0]; 42 | if (arg instanceof Map) { 43 | Map params = (Map) arg; 44 | String queryHistoryDate = MapUtil.getStr(params, "queryHistoryDate"); 45 | log.info("queryDate:{}", queryHistoryDate); 46 | if (StrUtil.isNotEmpty(queryHistoryDate)) { 47 | // 获取注解的 class 参数 48 | MethodSignature signature = (MethodSignature) joinPoint.getSignature(); 49 | Method method = signature.getMethod(); 50 | ShardingQueryData entityTableClass = method.getAnnotation(ShardingQueryData.class); 51 | Class entityClass = entityTableClass.tableEntity(); 52 | // 设置分表 53 | String shardingTable = ShardingTableConfig.isExistShardingTable(entityClass, queryHistoryDate); 54 | if (StrUtil.isNotEmpty(shardingTable)) { 55 | ShardingTableConfig.setTableName(shardingTable); 56 | } else { 57 | throw new RRException("暂无数据", 0); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | /** 65 | * 还原分表 66 | * 67 | * @param joinPoint 68 | */ 69 | @After("queryMethod()") 70 | public void afterAdvice(JoinPoint joinPoint) { 71 | ShardingTableConfig.removeTableName(); 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/entity/XMessageServiceSendRecord.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import com.fasterxml.jackson.annotation.JsonFormat; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.suke.czx.common.annotation.ShardingTable; 9 | import com.suke.czx.modules.tenancy.entity.TenancyBase; 10 | import io.swagger.v3.oas.annotations.media.Schema; 11 | import lombok.Data; 12 | import lombok.EqualsAndHashCode; 13 | 14 | import java.io.Serializable; 15 | import java.util.Date; 16 | 17 | 18 | /** 19 | * 短信发送记录(按月分表) 20 | * 21 | * @author czx 22 | * @email object_czx@163.com 23 | * @date 2025-08-15 17:40:53 24 | */ 25 | @Data 26 | @ShardingTable 27 | @EqualsAndHashCode(callSuper = true) 28 | @TableName("x_message_service_send_record") 29 | public class XMessageServiceSendRecord extends TenancyBase implements Serializable { 30 | 31 | public static final long serialVersionUID = 1L; 32 | 33 | @TableId(type = IdType.AUTO) 34 | @Schema(description = "记录ID") 35 | @JsonProperty(value = "recordId") 36 | public Integer recordId; 37 | 38 | @Schema(description = "应用ID") 39 | @JsonProperty(value = "appId") 40 | public Integer appId; 41 | 42 | @Schema(description = "创建时间") 43 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 44 | @JsonProperty(value = "createTime") 45 | public Date createTime; 46 | 47 | @Schema(description = "日") 48 | @JsonProperty(value = "recordDay") 49 | public Integer recordDay; 50 | 51 | @Schema(description = "月") 52 | @JsonProperty(value = "recordMonth") 53 | public Integer recordMonth; 54 | 55 | @Schema(description = "年") 56 | @JsonProperty(value = "recordYear") 57 | public Integer recordYear; 58 | 59 | @Schema(description = "内容") 60 | @JsonProperty(value = "sendContent") 61 | public String sendContent; 62 | 63 | @Schema(description = "手机号") 64 | @JsonProperty(value = "sendMobile") 65 | public String sendMobile; 66 | 67 | @Schema(description = "发送来源") 68 | @JsonProperty(value = "sendSource") 69 | public String sendSource; 70 | 71 | @Schema(description = "发送状态") 72 | @JsonProperty(value = "sendStatus") 73 | public Integer sendStatus; 74 | 75 | @Schema(description = "发送类型") 76 | @JsonProperty(value = "sendType") 77 | public String sendType; 78 | 79 | @Schema(description = "服务ID") 80 | @JsonProperty(value = "serviceId") 81 | public Integer serviceId; 82 | 83 | @Schema(description = "模板ID") 84 | @JsonProperty(value = "templateId") 85 | public Integer templateId; 86 | 87 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/controller/XMessageServiceSendRecordController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.controller; 2 | 3 | import cn.hutool.core.map.MapUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 | import com.baomidou.mybatisplus.core.metadata.IPage; 7 | import com.suke.czx.common.annotation.ResourceAuth; 8 | import com.suke.czx.common.base.AbstractController; 9 | import com.suke.czx.common.shardingtable.ShardingQueryData; 10 | import com.suke.czx.common.utils.R; 11 | import com.suke.czx.modules.msg.entity.XMessageServiceSendRecord; 12 | import com.suke.czx.modules.msg.service.XMessageServiceSendRecordService; 13 | import io.swagger.v3.oas.annotations.tags.Tag; 14 | import lombok.AllArgsConstructor; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RequestParam; 18 | import org.springframework.web.bind.annotation.RestController; 19 | 20 | import java.util.Map; 21 | 22 | 23 | /** 24 | * 短信发送记录(按月分表) 25 | * 26 | * @author czx 27 | * @email object_czx@163.com 28 | * @date 2025-08-15 17:40:53 29 | */ 30 | @RestController 31 | @AllArgsConstructor 32 | @RequestMapping("/msg/record") 33 | @Tag(name = "XMessageServiceSendRecordController", description = "短信发送记录(按月分表)") 34 | public class XMessageServiceSendRecordController extends AbstractController { 35 | private final XMessageServiceSendRecordService xMessageServiceSendRecordService; 36 | 37 | /** 38 | * 列表 39 | */ 40 | @ShardingQueryData(tableEntity = XMessageServiceSendRecord.class) 41 | @GetMapping("/list") 42 | @ResourceAuth(value = "短信发送记录(按月分表)列表", module = "短信发送记录(按月分表)") 43 | public R list(@RequestParam Map params) { 44 | //查询列表数据 45 | QueryWrapper queryWrapper = new QueryWrapper<>(); 46 | final String keyword = mpPageConvert.getKeyword(params); 47 | if (StrUtil.isNotEmpty(keyword)) { 48 | queryWrapper.lambda().and(func -> { 49 | func.like(XMessageServiceSendRecord::getSendContent, keyword).or().eq(XMessageServiceSendRecord::getSendMobile, keyword); 50 | }); 51 | } 52 | 53 | String tenancyId = MapUtil.getStr(params, "tenancyId"); 54 | if (StrUtil.isNotEmpty(tenancyId)) { 55 | queryWrapper.lambda().eq(XMessageServiceSendRecord::getTenancyId, tenancyId); 56 | } 57 | 58 | IPage listPage = xMessageServiceSendRecordService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 59 | this.fullTenancyInfo(listPage); 60 | return R.ok().setData(listPage); 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/provider/CustomAuthorizationManager.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.provider; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import com.suke.czx.common.utils.Constant; 5 | import com.suke.czx.common.utils.URLConvertUtil; 6 | import com.suke.czx.common.utils.UserUtil; 7 | import com.suke.czx.config.AuthIgnoreConfig; 8 | import jakarta.annotation.Resource; 9 | import org.springframework.security.authentication.AnonymousAuthenticationToken; 10 | import org.springframework.security.authorization.AuthorizationDecision; 11 | import org.springframework.security.authorization.AuthorizationManager; 12 | import org.springframework.security.core.Authentication; 13 | import org.springframework.security.core.GrantedAuthority; 14 | import org.springframework.security.web.access.intercept.RequestAuthorizationContext; 15 | 16 | import java.util.Collection; 17 | import java.util.List; 18 | import java.util.function.Supplier; 19 | 20 | 21 | /** 22 | * 自定义授权管理器 23 | */ 24 | public class CustomAuthorizationManager implements AuthorizationManager { 25 | 26 | @Resource 27 | private AuthIgnoreConfig authIgnoreConfig; 28 | 29 | 30 | @Override 31 | public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) { 32 | String requestUrl = context.getRequest().getServletPath(); 33 | Collection authorities = authentication.get().getAuthorities(); 34 | 35 | // 如果URL中包含参数,则把参数去掉 36 | if (requestUrl.contains("?")) { 37 | requestUrl = requestUrl.substring(0, requestUrl.indexOf("?")); 38 | } 39 | 40 | // 如果URL是不需要认证的 直接返回通过 41 | List ignoreUrls = authIgnoreConfig.getIgnoreUrls(); 42 | if (CollUtil.isNotEmpty(ignoreUrls) && authIgnoreConfig.match(requestUrl)) { 43 | // 如果是忽略认证的设置为authIgnore 44 | return new AuthorizationDecision(true); 45 | } 46 | 47 | // 如果是匿名用户则直接返回不通过 48 | if (authentication.get() instanceof AnonymousAuthenticationToken) { 49 | return new AuthorizationDecision(false); 50 | } 51 | 52 | String userId = UserUtil.getUserId(); 53 | // 如果是超级管理员则直接返回通过 54 | if (userId.equals(Constant.SUPER_ADMIN)) { 55 | return new AuthorizationDecision(true); 56 | } else { 57 | String role = URLConvertUtil.convert(requestUrl); 58 | for (GrantedAuthority authority : authorities) { 59 | //判断当前用户是否有对应权限,有则放行 60 | if (role.equals(authority.getAuthority())) { 61 | return new AuthorizationDecision(true); 62 | } 63 | } 64 | return new AuthorizationDecision(false); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/apk/entity/TbApkVersion.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.apk.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import com.fasterxml.jackson.annotation.JsonFormat; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | import lombok.Data; 10 | 11 | import java.io.Serializable; 12 | import java.util.Date; 13 | 14 | 15 | /** 16 | * APK版本管理 17 | * 18 | * @author czx 19 | * @email object_czx@163.com 20 | * @date 2023-01-26 20:32:33 21 | */ 22 | @Data 23 | @TableName("tb_apk_version") 24 | public class TbApkVersion implements Serializable { 25 | public static final long serialVersionUID = 1L; 26 | 27 | @TableId(type = IdType.AUTO) 28 | @Schema(description = "") 29 | @JsonProperty(value = "id") 30 | public Long id; 31 | 32 | @Schema(description = "更新内容") 33 | @JsonProperty(value = "updateContent") 34 | public String updateContent; 35 | 36 | @Schema(description = "版本码") 37 | @JsonProperty(value = "versionCode") 38 | public Integer versionCode; 39 | 40 | @Schema(description = "版本号") 41 | @JsonProperty(value = "versionName") 42 | public String versionName; 43 | 44 | @Schema(description = "包名") 45 | @JsonProperty(value = "packageName") 46 | public String packageName; 47 | 48 | @Schema(description = "下载地址") 49 | @JsonProperty(value = "downloadUrl") 50 | public String downloadUrl; 51 | 52 | @Schema(description = "APP名") 53 | @JsonProperty(value = "appName") 54 | public String appName; 55 | 56 | @Schema(description = "MD5值") 57 | @JsonProperty(value = "md5Value") 58 | public String md5Value; 59 | 60 | @Schema(description = "文件名") 61 | @JsonProperty(value = "fileName") 62 | public String fileName; 63 | 64 | @Schema(description = "文件大小") 65 | @JsonProperty(value = "fileSize") 66 | public String fileSize; 67 | 68 | @Schema(description = "是否强制安装") 69 | @JsonProperty(value = "isForce") 70 | public Integer isForce; 71 | 72 | @Schema(description = "是否可忽略该版本") 73 | @JsonProperty(value = "isIgnorable") 74 | public Integer isIgnorable; 75 | 76 | @Schema(description = "是否静默下载") 77 | @JsonProperty(value = "isSilent") 78 | public Integer isSilent; 79 | 80 | @Schema(description = "上传人") 81 | @JsonProperty(value = "userId") 82 | public String userId; 83 | 84 | @Schema(description = "创建时间") 85 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 86 | @JsonProperty(value = "createTime") 87 | public Date createTime; 88 | 89 | @Schema(description = "修改时间") 90 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 91 | @JsonProperty(value = "updateTime") 92 | public Date updateTime; 93 | 94 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/service/impl/XMessageServiceServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.service.impl; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.suke.czx.modules.msg.entity.XMessageService; 7 | import com.suke.czx.modules.msg.entity.XMessageServiceTemplateConfig; 8 | import com.suke.czx.modules.msg.mapper.XMessageServiceMapper; 9 | import com.suke.czx.modules.msg.mapper.XMessageServiceTemplateConfigMapper; 10 | import com.suke.czx.modules.msg.service.XMessageServiceService; 11 | import lombok.AllArgsConstructor; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | 19 | /** 20 | * 短信服务 21 | * 22 | * @author czx 23 | * @email object_czx@163.com 24 | * @date 2025-08-15 17:51:27 25 | */ 26 | @Service 27 | @AllArgsConstructor 28 | public class XMessageServiceServiceImpl extends ServiceImpl implements XMessageServiceService { 29 | 30 | private final XMessageServiceTemplateConfigMapper xMessageServiceTemplateConfigMapper; 31 | 32 | @Override 33 | @Transactional 34 | public void saveInfo(XMessageService param) { 35 | baseMapper.insert(param); 36 | this.saveConfig(param); 37 | } 38 | 39 | @Override 40 | @Transactional 41 | public void updateInfo(XMessageService param) { 42 | baseMapper.updateById(param); 43 | if (param.getTemplateIds() != null) { 44 | xMessageServiceTemplateConfigMapper.delete(Wrappers.lambdaQuery().eq(XMessageServiceTemplateConfig::getServiceId, param.getServiceId())); 45 | this.saveConfig(param); 46 | } 47 | } 48 | 49 | @Override 50 | @Transactional 51 | public void deleteInfo(XMessageService param) { 52 | xMessageServiceTemplateConfigMapper.delete(Wrappers.lambdaQuery().eq(XMessageServiceTemplateConfig::getServiceId, param.getServiceId())); 53 | baseMapper.deleteById(param.getServiceId()); 54 | } 55 | 56 | @Transactional 57 | public void saveConfig(XMessageService param) { 58 | if (param.getTemplateIds() != null) { 59 | List configs = Arrays.stream(param.getTemplateIds()).map(item -> { 60 | XMessageServiceTemplateConfig config = new XMessageServiceTemplateConfig(); 61 | config.setServiceId(param.getServiceId()); 62 | config.setTemplateId(item); 63 | return config; 64 | }).toList(); 65 | if (CollUtil.isNotEmpty(configs)) { 66 | xMessageServiceTemplateConfigMapper.insert(configs); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/interceptor/ValidateCodeFilter.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.interceptor; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.suke.czx.common.exception.CustomAuthenticationException; 5 | import com.suke.czx.common.utils.Constant; 6 | import jakarta.servlet.FilterChain; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletResponse; 9 | import lombok.SneakyThrows; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.data.redis.core.RedisTemplate; 12 | import org.springframework.security.web.authentication.AuthenticationFailureHandler; 13 | import org.springframework.util.AntPathMatcher; 14 | import org.springframework.web.filter.OncePerRequestFilter; 15 | 16 | /** 17 | * @author czx 18 | * @description: 验证码拦截器 19 | * @date 2019/12/2416:29 20 | */ 21 | @Slf4j 22 | public class ValidateCodeFilter extends OncePerRequestFilter { 23 | 24 | private final AntPathMatcher pathMatcher = new AntPathMatcher(); 25 | private final RedisTemplate redisTemplate; 26 | private final AuthenticationFailureHandler authenticationFailureHandler; 27 | 28 | public ValidateCodeFilter(RedisTemplate redisTemplate, AuthenticationFailureHandler authenticationFailureHandler){ 29 | this.redisTemplate = redisTemplate; 30 | this.authenticationFailureHandler = authenticationFailureHandler; 31 | } 32 | 33 | @SneakyThrows 34 | @Override 35 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { 36 | String url = request.getRequestURI(); 37 | if (pathMatcher.match(Constant.TOKEN_ENTRY_POINT_URL,url)){ 38 | String captcha = request.getParameter("captcha"); 39 | String randomStr = request.getParameter("randomStr"); 40 | 41 | if(StrUtil.isBlank(captcha) || StrUtil.isBlank(randomStr)){ 42 | CustomAuthenticationException exception = new CustomAuthenticationException("验证码为空"); 43 | authenticationFailureHandler.onAuthenticationFailure(request,response,exception); 44 | return; 45 | } 46 | 47 | String code_key = (String) redisTemplate.opsForValue().get(Constant.NUMBER_CODE_KEY + randomStr); 48 | if(StrUtil.isEmpty(code_key)){ 49 | CustomAuthenticationException exception = new CustomAuthenticationException("验证码过期"); 50 | authenticationFailureHandler.onAuthenticationFailure(request,response,exception); 51 | return; 52 | } 53 | 54 | if(!captcha.equalsIgnoreCase(code_key)){ 55 | CustomAuthenticationException exception = new CustomAuthenticationException("验证码不正确"); 56 | authenticationFailureHandler.onAuthenticationFailure(request,response,exception); 57 | return; 58 | } 59 | } 60 | filterChain.doFilter(request,response); 61 | } 62 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/cloud/QiniuCloudStorageService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.cloud; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.qiniu.http.Response; 5 | import com.qiniu.storage.UploadManager; 6 | import com.qiniu.util.Auth; 7 | import com.suke.czx.common.exception.RRException; 8 | import com.suke.czx.modules.oss.entity.SysOssSetting; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.apache.commons.io.IOUtils; 11 | import org.springframework.web.multipart.MultipartFile; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | 16 | /** 17 | * 七牛云存储 18 | * 19 | * @author czx 20 | * @email object_czx@163.com 21 | * @date 2017-03-25 15:41 22 | */ 23 | @Slf4j 24 | public class QiniuCloudStorageService implements ICloudStorage { 25 | 26 | private final Auth auth; 27 | private final UploadManager uploadManager; 28 | private final SysOssSetting config; 29 | 30 | public QiniuCloudStorageService(SysOssSetting config) { 31 | this.config = config; 32 | auth = Auth.create(config.getAccessKey(), config.getSecretKey()); 33 | uploadManager = new UploadManager(new com.qiniu.storage.Configuration()); 34 | } 35 | 36 | @Override 37 | public String upload(MultipartFile file, String objectName) { 38 | try { 39 | if (StrUtil.isNotEmpty(config.getPrefix())) { 40 | objectName = "uploads/" + config.getPrefix() + "/" + objectName; 41 | } else { 42 | objectName = "uploads/" + objectName; 43 | } 44 | return upload(file.getBytes(), objectName); 45 | } catch (Exception e) { 46 | throw new RRException("上传七牛出错:" + e.getMessage()); 47 | } 48 | } 49 | 50 | @Override 51 | public String upload(byte[] data, String path) { 52 | try { 53 | String token = auth.uploadToken(config.getBucketName()); 54 | Response res = uploadManager.put(data, path, token); 55 | if (!res.isOK()) { 56 | throw new RRException("上传七牛出错:" + res.getInfo()); 57 | } 58 | } catch (Exception e) { 59 | throw new RRException("上传文件失败,请核对七牛配置信息", e); 60 | } 61 | 62 | return config.getView() + "/" + path; 63 | } 64 | 65 | @Override 66 | public String upload(InputStream inputStream, String path) { 67 | try { 68 | byte[] data = IOUtils.toByteArray(inputStream); 69 | return this.upload(data, path); 70 | } catch (IOException e) { 71 | throw new RRException("上传文件失败", e); 72 | } 73 | } 74 | 75 | @Override 76 | public String uploadSuffix(byte[] data, String suffix) { 77 | return upload(data, getPath(config.getPrefix(), suffix)); 78 | } 79 | 80 | @Override 81 | public String uploadSuffix(InputStream inputStream, String suffix) { 82 | return upload(inputStream, getPath(config.getPrefix(), suffix)); 83 | } 84 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/service/impl/SysUserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.service.impl; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.suke.czx.modules.sys.entity.SysUser; 7 | import com.suke.czx.modules.sys.entity.SysUserRole; 8 | import com.suke.czx.modules.sys.mapper.SysUserMapper; 9 | import com.suke.czx.modules.sys.mapper.SysUserRoleMapper; 10 | import com.suke.czx.modules.sys.service.SysUserService; 11 | import lombok.AllArgsConstructor; 12 | import org.apache.commons.lang.StringUtils; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.transaction.annotation.Transactional; 16 | 17 | import java.util.Date; 18 | 19 | 20 | /** 21 | * 系统用户 22 | * 23 | * @author czx 24 | * @email object_czx@163.com 25 | * @date 2016年9月18日 上午9:46:09 26 | */ 27 | @Service 28 | @AllArgsConstructor 29 | public class SysUserServiceImpl extends ServiceImpl implements SysUserService { 30 | private final SysUserMapper sysUserMapper; 31 | private final SysUserRoleMapper sysUserRoleMapper; 32 | private final PasswordEncoder passwordEncoder; 33 | 34 | 35 | @Override 36 | @Transactional 37 | public void saveUserRole(SysUser user) { 38 | user.setCreateTime(new Date()); 39 | user.setPassword(passwordEncoder.encode(user.getPassword())); 40 | sysUserMapper.insert(user); 41 | sysUserRoleMapper.delete(Wrappers.update().lambda().eq(SysUserRole::getUserId, user.getUserId())); 42 | //保存用户与角色关系 43 | saveUserRoleList(user); 44 | } 45 | 46 | @Override 47 | @Transactional 48 | public void updateUserRole(SysUser user) { 49 | if (StringUtils.isBlank(user.getPassword())) { 50 | user.setPassword(null); 51 | } else { 52 | user.setPassword(passwordEncoder.encode(user.getPassword())); 53 | } 54 | baseMapper.updateById(user); 55 | sysUserRoleMapper.delete(Wrappers.update().lambda().eq(SysUserRole::getUserId, user.getUserId())); 56 | //保存用户与角色关系 57 | saveUserRoleList(user); 58 | } 59 | 60 | 61 | @Override 62 | public int updatePassword(String userId, String password, String newPassword) { 63 | SysUser sysUser = new SysUser(); 64 | sysUser.setUserId(userId); 65 | sysUser.setPassword(newPassword); 66 | return sysUserMapper.updateById(sysUser); 67 | } 68 | 69 | public void saveUserRoleList(SysUser user) { 70 | if (CollUtil.isNotEmpty(user.getRoleIdList())) { 71 | user.getRoleIdList().forEach(roleId -> { 72 | SysUserRole userRole = new SysUserRole(); 73 | userRole.setUserId(user.getUserId()); 74 | userRole.setRoleId(roleId); 75 | sysUserRoleMapper.insert(userRole); 76 | }); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | 4 | import com.suke.czx.common.utils.Constant; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.data.redis.cache.RedisCacheConfiguration; 10 | import org.springframework.data.redis.cache.RedisCacheManager; 11 | import org.springframework.data.redis.connection.RedisConnectionFactory; 12 | import org.springframework.data.redis.core.*; 13 | import org.springframework.data.redis.serializer.RedisSerializationContext; 14 | import org.springframework.data.redis.serializer.RedisSerializer; 15 | 16 | import java.time.Duration; 17 | 18 | @Slf4j 19 | @EnableCaching 20 | @Configuration 21 | public class RedisConfig { 22 | 23 | @Bean 24 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 25 | RedisTemplate redisTemplate = new RedisTemplate<>(); 26 | redisTemplate.setKeySerializer(RedisSerializer.string()); 27 | redisTemplate.setHashKeySerializer(RedisSerializer.string()); 28 | redisTemplate.setValueSerializer(RedisSerializer.java()); 29 | redisTemplate.setHashValueSerializer(RedisSerializer.java()); 30 | redisTemplate.setConnectionFactory(factory); 31 | return redisTemplate; 32 | } 33 | 34 | @Bean 35 | public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { 36 | RedisCacheConfiguration configuration = RedisCacheConfiguration 37 | .defaultCacheConfig() 38 | .computePrefixWith(cacheName -> Constant.SYSTEM_CACHE + cacheName) 39 | .entryTtl(Duration.ofDays(7)) // 7天过期 40 | .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string())) 41 | .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.java())); 42 | return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(configuration).build(); 43 | } 44 | 45 | @Bean 46 | public HashOperations hashOperations(RedisTemplate redisTemplate) { 47 | return redisTemplate.opsForHash(); 48 | } 49 | 50 | @Bean 51 | public ValueOperations valueOperations(RedisTemplate redisTemplate) { 52 | return redisTemplate.opsForValue(); 53 | } 54 | 55 | @Bean 56 | public ListOperations listOperations(RedisTemplate redisTemplate) { 57 | return redisTemplate.opsForList(); 58 | } 59 | 60 | @Bean 61 | public SetOperations setOperations(RedisTemplate redisTemplate) { 62 | return redisTemplate.opsForSet(); 63 | } 64 | 65 | @Bean 66 | public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { 67 | return redisTemplate.opsForZSet(); 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/detail/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.detail; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import cn.hutool.core.util.ObjectUtil; 5 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 6 | import com.suke.czx.modules.sys.entity.SysUser; 7 | import com.suke.czx.modules.sys.service.SysUserService; 8 | import jakarta.annotation.Resource; 9 | import org.springframework.security.core.GrantedAuthority; 10 | import org.springframework.security.core.authority.AuthorityUtils; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | import org.springframework.security.core.userdetails.UserDetailsService; 13 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 14 | import org.springframework.stereotype.Component; 15 | 16 | import java.util.Collection; 17 | import java.util.Set; 18 | 19 | /** 20 | * @Description 自定义用户认证 21 | * @Date 21:09 22 | * @Author yzcheng90@qq.com 23 | **/ 24 | @Component 25 | public class CustomUserDetailsService implements UserDetailsService { 26 | 27 | @Resource 28 | private SysUserService sysUserService; 29 | 30 | @Resource 31 | private PermissionsService permissionsService; 32 | 33 | 34 | @Override 35 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 36 | SysUser sysUser = sysUserService.getOne(Wrappers.query().lambda().eq(SysUser::getUsername, username)); 37 | if (ObjectUtil.isNull(sysUser)) { 38 | throw new UsernameNotFoundException("用户不存在"); 39 | } 40 | return getDetail(sysUser); 41 | } 42 | 43 | public UserDetails loadUserByUserId(String userId) throws UsernameNotFoundException { 44 | SysUser sysUser = sysUserService.getById(userId); 45 | if (ObjectUtil.isNull(sysUser)) { 46 | throw new UsernameNotFoundException("用户不存在"); 47 | } 48 | return getDetail(sysUser); 49 | } 50 | 51 | private UserDetails getDetail(SysUser sysUser) { 52 | Set permissions = permissionsService.getUserPermissions(sysUser.getUserId()); 53 | String[] roles = new String[0]; 54 | if (CollUtil.isNotEmpty(permissions)) { 55 | roles = permissions.toArray(String[]::new); 56 | } 57 | Collection authorities = AuthorityUtils.createAuthorityList(roles); 58 | 59 | // 是否允许账号登录 60 | boolean enabled = sysUser.getStatus() == null || sysUser.getStatus() != 0; 61 | //帐户未过期 62 | boolean accountNonExpired = true; 63 | //帐户未锁定 64 | boolean accountNonLocked = true; 65 | //证书未过期 66 | boolean credentialsNonExpired = true; 67 | 68 | return new CustomUserDetailsUser(sysUser.getTenancyId(), 69 | sysUser.getUserId(), 70 | sysUser.getUsername(), 71 | sysUser.getPassword(), 72 | enabled, 73 | accountNonExpired, 74 | accountNonLocked, 75 | credentialsNonExpired, 76 | authorities); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/AuthIgnoreConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import cn.hutool.core.util.ReUtil; 4 | import com.suke.czx.common.annotation.AuthIgnore; 5 | import jakarta.annotation.Resource; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.InitializingBean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.core.annotation.AnnotationUtils; 12 | import org.springframework.util.AntPathMatcher; 13 | import org.springframework.web.context.WebApplicationContext; 14 | import org.springframework.web.method.HandlerMethod; 15 | import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition; 16 | import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; 17 | import org.springframework.web.servlet.mvc.method.RequestMappingInfo; 18 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.Map; 23 | import java.util.regex.Pattern; 24 | 25 | /** 26 | * @author czx 27 | * @title: AuthIgnoreConfig 28 | * @projectName x-springboot 29 | * @description: 忽略权限认证 30 | * @date 2019/12/2415:56 31 | */ 32 | @Slf4j 33 | @Configuration 34 | public class AuthIgnoreConfig implements InitializingBean { 35 | 36 | @Resource 37 | private WebApplicationContext applicationContext; 38 | 39 | private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); 40 | private static final String ASTERISK = "*"; 41 | 42 | private final AntPathMatcher antPathMatcher = new AntPathMatcher(); 43 | 44 | @Getter 45 | @Setter 46 | private List ignoreUrls = new ArrayList<>(); 47 | 48 | @Override 49 | public void afterPropertiesSet(){ 50 | RequestMappingHandlerMapping mapping = applicationContext.getBean("requestMappingHandlerMapping",RequestMappingHandlerMapping.class); 51 | Map map = mapping.getHandlerMethods(); 52 | map.keySet().forEach(mappingInfo -> { 53 | HandlerMethod handlerMethod = map.get(mappingInfo); 54 | AuthIgnore method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), AuthIgnore.class); 55 | if(method != null){ 56 | PathPatternsRequestCondition pathPatternsCondition = mappingInfo.getPathPatternsCondition(); 57 | if(pathPatternsCondition != null){ 58 | pathPatternsCondition.getPatterns().forEach(url ->{ 59 | String patternString = url.getPatternString(); 60 | ignoreUrls.add(ReUtil.replaceAll(patternString, PATTERN, ASTERISK)); 61 | }); 62 | } 63 | } 64 | }); 65 | } 66 | 67 | public boolean isContains(String url) { 68 | final String u = ReUtil.replaceAll(url, PATTERN, ASTERISK); 69 | return ignoreUrls.contains(u); 70 | } 71 | 72 | public boolean match(String url) { 73 | long count = ignoreUrls.stream().filter(u -> antPathMatcher.match(u, url)).count(); 74 | return count > 0; 75 | } 76 | } -------------------------------------------------------------------------------- /src/main/resources/template/Controller.java.vm: -------------------------------------------------------------------------------- 1 | package ${package}.${moduleName}.controller; 2 | 3 | import java.util.Map; 4 | 5 | import cn.hutool.core.util.StrUtil; 6 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 7 | import com.baomidou.mybatisplus.core.metadata.IPage; 8 | import org.springframework.web.bind.annotation.*; 9 | import ${package}.${moduleName}.entity.${className}; 10 | import ${package}.${moduleName}.service.${className}Service; 11 | import com.suke.czx.common.utils.R; 12 | import io.swagger.v3.oas.annotations.tags.Tag; 13 | import lombok.AllArgsConstructor; 14 | import com.suke.czx.common.annotation.SysLog; 15 | import com.suke.czx.common.annotation.ResourceAuth; 16 | import com.suke.czx.common.base.AbstractController; 17 | 18 | 19 | /** 20 | * ${comments} 21 | * 22 | * @author ${author} 23 | * @email ${email} 24 | * @date ${datetime} 25 | */ 26 | @RestController 27 | @AllArgsConstructor 28 | @RequestMapping("/${moduleName}/${requestMapping}") 29 | @Tag(name = "${className}Controller", description = "${comments}") 30 | public class ${className}Controller extends AbstractController { 31 | private final ${className}Service ${classname}Service; 32 | 33 | /** 34 | * 列表 35 | */ 36 | @GetMapping("/list") 37 | @ResourceAuth(value = "${comments}列表", module = "${comments}") 38 | public R list(@RequestParam Map params) { 39 | //查询列表数据 40 | QueryWrapper<${className}> queryWrapper = new QueryWrapper<>(); 41 | final String keyword = mpPageConvert.getKeyword(params); 42 | if (StrUtil.isNotEmpty(keyword)) { 43 | 44 | } 45 | IPage<${className}> listPage = ${classname}Service.page(mpPageConvert.<${className}>pageParamConvert(params), queryWrapper); 46 | return R.ok().setData(listPage); 47 | } 48 | 49 | 50 | /** 51 | * 新增${comments} 52 | */ 53 | @SysLog("新增${comments}数据") 54 | #if($useRestful) 55 | @PutMapping("/${requestMapping}") 56 | #else 57 | @PostMapping("/save") 58 | #end 59 | @ResourceAuth(value = "新增${comments}数据", module = "${comments}") 60 | public R save(@RequestBody ${className} param) { 61 | ${classname}Service.save(param); 62 | return R.ok(); 63 | } 64 | 65 | 66 | /** 67 | * 修改 68 | */ 69 | @SysLog("修改${comments}数据") 70 | #if($useRestful) 71 | @PutMapping("/${requestMapping}") 72 | #else 73 | @PostMapping("/update") 74 | #end 75 | @ResourceAuth(value = "修改${comments}数据", module = "${comments}") 76 | public R update(@RequestBody ${className} param) { 77 | ${classname}Service.updateById(param); 78 | return R.ok(); 79 | } 80 | 81 | 82 | /** 83 | * 删除 84 | */ 85 | @SysLog("删除${comments}数据") 86 | #if($useRestful) 87 | @DeleteMapping("/${requestMapping}") 88 | #else 89 | @PostMapping("/delete") 90 | #end 91 | @ResourceAuth(value = "删除${comments}数据", module = "${comments}") 92 | public R delete(@RequestBody ${className} param) { 93 | ${classname}Service.removeById(param.get${pk.attrName}()); 94 | return R.ok(); 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/sys/controller/SysLogController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.sys.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.suke.czx.common.annotation.ResourceAuth; 7 | import com.suke.czx.common.base.AbstractController; 8 | import com.suke.czx.modules.sys.entity.SysLog; 9 | import com.suke.czx.modules.sys.entity.SysLoginLog; 10 | import com.suke.czx.modules.sys.service.SysLogService; 11 | import com.suke.czx.modules.sys.service.SysLoginLogService; 12 | import com.suke.czx.common.utils.R; 13 | import io.swagger.v3.oas.annotations.tags.Tag; 14 | import lombok.AllArgsConstructor; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RequestParam; 18 | import org.springframework.web.bind.annotation.RestController; 19 | 20 | import java.util.Map; 21 | 22 | 23 | /** 24 | * 系统日志 25 | * 26 | * @author czx 27 | * @email object_czx@163.com 28 | */ 29 | @RestController 30 | @AllArgsConstructor 31 | @Tag(name = "SysLogController", description = "系统日志") 32 | @RequestMapping("/sys/log") 33 | public class SysLogController extends AbstractController { 34 | private final SysLogService sysLogService; 35 | private final SysLoginLogService sysLoginLogService; 36 | 37 | /** 38 | * 列表 39 | */ 40 | @GetMapping(value = "/list") 41 | @ResourceAuth(value = "系统日志列表", module = "系统日志") 42 | public R list(@RequestParam Map params) { 43 | //查询列表数据 44 | QueryWrapper queryWrapper = new QueryWrapper<>(); 45 | final String keyword = mpPageConvert.getKeyword(params); 46 | if (StrUtil.isNotEmpty(keyword)) { 47 | queryWrapper 48 | .lambda() 49 | .like(SysLog::getUsername, keyword) 50 | .or() 51 | .like(SysLog::getOperation, keyword); 52 | } 53 | queryWrapper.lambda().orderByDesc(SysLog::getCreateDate); 54 | IPage listPage = sysLogService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 55 | return R.ok().setData(listPage); 56 | } 57 | 58 | /** 59 | * 列表 60 | */ 61 | @GetMapping(value = "/loginList") 62 | @ResourceAuth(value = "登录日志列表", module = "系统日志") 63 | public R loginList(@RequestParam Map params) { 64 | //查询列表数据 65 | QueryWrapper queryWrapper = new QueryWrapper<>(); 66 | final String keyword = mpPageConvert.getKeyword(params); 67 | if (StrUtil.isNotEmpty(keyword)) { 68 | queryWrapper 69 | .lambda() 70 | .like(SysLoginLog::getUsername, keyword) 71 | .or() 72 | .like(SysLoginLog::getOptionName, keyword); 73 | } 74 | queryWrapper.lambda().orderByDesc(SysLoginLog::getOptionTime); 75 | IPage listPage = sysLoginLogService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 76 | return R.ok().setData(listPage); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/handler/CustomAuthenticationSuccessHandler.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.handler; 2 | 3 | import cn.hutool.core.util.CharsetUtil; 4 | import cn.hutool.crypto.SecureUtil; 5 | import cn.hutool.json.JSONUtil; 6 | import com.suke.czx.authentication.detail.CustomUserDetailsUser; 7 | import com.suke.czx.common.event.LoginLogEvent; 8 | import com.suke.czx.common.utils.Constant; 9 | import com.suke.czx.common.utils.IPUtils; 10 | import com.suke.czx.common.utils.R; 11 | import com.suke.czx.common.utils.SpringContextUtils; 12 | import com.suke.czx.modules.sys.entity.SysLoginLog; 13 | 14 | import jakarta.annotation.Resource; 15 | import jakarta.servlet.http.HttpServletRequest; 16 | import jakarta.servlet.http.HttpServletResponse; 17 | import lombok.SneakyThrows; 18 | import lombok.extern.slf4j.Slf4j; 19 | import org.springframework.data.redis.core.RedisTemplate; 20 | import org.springframework.http.MediaType; 21 | import org.springframework.security.core.Authentication; 22 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 23 | import org.springframework.stereotype.Component; 24 | 25 | import java.io.PrintWriter; 26 | import java.util.Date; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | /** 30 | * @Description 31 | * @Date 21:06 32 | * @Author yzcheng90@qq.com 33 | **/ 34 | @Slf4j 35 | @Component 36 | public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { 37 | 38 | @Resource 39 | private RedisTemplate redisTemplate; 40 | 41 | @SneakyThrows 42 | @Override 43 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { 44 | String token; 45 | String userId = ""; 46 | String userName = ""; 47 | if (authentication.getPrincipal() instanceof CustomUserDetailsUser) { 48 | CustomUserDetailsUser userDetailsUser = (CustomUserDetailsUser) authentication.getPrincipal(); 49 | token = SecureUtil.md5(userDetailsUser.getUsername() + System.currentTimeMillis()); 50 | userId = userDetailsUser.getUserId(); 51 | userName = userDetailsUser.getUsername(); 52 | } else { 53 | token = SecureUtil.md5(String.valueOf(System.currentTimeMillis())); 54 | } 55 | // 保存token 56 | redisTemplate.opsForValue().set(Constant.AUTHENTICATION_TOKEN + token, userId + "," + userName, Constant.TOKEN_EXPIRE, TimeUnit.SECONDS); 57 | log.info("用户ID:{},用户名:{},登录成功! token:{}", userId, userName, token); 58 | 59 | SysLoginLog loginLog = new SysLoginLog(); 60 | loginLog.setOptionIp(IPUtils.getIpAddr(request)); 61 | loginLog.setOptionName("用户登录成功"); 62 | loginLog.setOptionTerminal(request.getHeader("User-Agent")); 63 | loginLog.setUsername(userName); 64 | loginLog.setOptionTime(new Date()); 65 | SpringContextUtils.publishEvent(new LoginLogEvent(loginLog)); 66 | 67 | response.setCharacterEncoding(CharsetUtil.UTF_8); 68 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 69 | PrintWriter printWriter = response.getWriter(); 70 | printWriter.append(JSONUtil.toJsonStr(R.ok().put(Constant.TOKEN, token))); 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/config/PermissionConfig.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.config; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import com.suke.czx.authentication.role.PermissionEntity; 5 | import com.suke.czx.common.annotation.ResourceAuth; 6 | import com.suke.czx.common.utils.URLConvertUtil; 7 | import jakarta.annotation.Resource; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.InitializingBean; 12 | import org.springframework.core.annotation.AnnotationUtils; 13 | import org.springframework.stereotype.Component; 14 | import org.springframework.util.AntPathMatcher; 15 | import org.springframework.web.context.WebApplicationContext; 16 | import org.springframework.web.method.HandlerMethod; 17 | import org.springframework.web.servlet.mvc.method.RequestMappingInfo; 18 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.Map; 23 | import java.util.stream.Collectors; 24 | 25 | /** 26 | * 权限收集 27 | */ 28 | @Slf4j 29 | @Component 30 | public class PermissionConfig implements InitializingBean { 31 | 32 | @Resource 33 | private WebApplicationContext applicationContext; 34 | 35 | @Getter 36 | @Setter 37 | private List permissionEntities = new ArrayList<>(); 38 | 39 | private final AntPathMatcher antPathMatcher = new AntPathMatcher(); 40 | 41 | @Override 42 | public void afterPropertiesSet() throws Exception { 43 | RequestMappingHandlerMapping mapping = applicationContext.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); 44 | Map map = mapping.getHandlerMethods(); 45 | map.keySet().forEach(mappingInfo -> { 46 | HandlerMethod handlerMethod = map.get(mappingInfo); 47 | ResourceAuth method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ResourceAuth.class); 48 | if (method != null) { 49 | PermissionEntity entity = new PermissionEntity(); 50 | entity.setName(method.value()); 51 | entity.setModuleName(method.module()); 52 | if(mappingInfo.getPathPatternsCondition() != null){ 53 | mappingInfo.getPathPatternsCondition().getPatternValues().forEach(url -> { 54 | String strUrl = URLConvertUtil.capture(url); 55 | String permission = URLConvertUtil.convert(url); 56 | entity.setUrl(strUrl); 57 | entity.setEnglishName(permission); 58 | permissionEntities.add(entity); 59 | }); 60 | } 61 | } 62 | }); 63 | } 64 | 65 | public PermissionEntity match(String url) { 66 | List entityList = permissionEntities 67 | .stream() 68 | .filter(permission -> antPathMatcher.match(permission.getUrl(), url)) 69 | .collect(Collectors.toList()); 70 | if (CollUtil.isNotEmpty(entityList)) { 71 | return entityList.getFirst(); 72 | } else { 73 | return null; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/authentication/utils/TokenUtils.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.authentication.utils; 2 | 3 | import cn.hutool.crypto.SecureUtil; 4 | import com.suke.czx.authentication.detail.CustomUserDetailsService; 5 | import com.suke.czx.authentication.detail.CustomUserDetailsUser; 6 | import com.suke.czx.common.utils.Constant; 7 | import com.suke.czx.common.utils.HttpContextUtils; 8 | import com.suke.czx.common.utils.SpringContextUtils; 9 | import jakarta.annotation.Resource; 10 | import jakarta.servlet.http.HttpServletRequest; 11 | import org.springframework.data.redis.core.RedisTemplate; 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 13 | import org.springframework.security.core.context.SecurityContextHolder; 14 | import org.springframework.security.core.userdetails.UserDetails; 15 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; 16 | import org.springframework.stereotype.Component; 17 | 18 | import java.util.concurrent.TimeUnit; 19 | 20 | /** 21 | * @author czx 22 | * @title: TokenUtils 23 | * @projectName life-helper 24 | * @description: 25 | * @date 2023/4/2015:20 26 | */ 27 | @Component 28 | public class TokenUtils { 29 | 30 | @Resource 31 | private RedisTemplate redisTemplate; 32 | 33 | public String generate() { 34 | String token = SecureUtil.md5(String.valueOf(System.currentTimeMillis())); 35 | return generate(token); 36 | } 37 | 38 | public String generate(CustomUserDetailsUser user) { 39 | String userId = user.getUserId(); 40 | String userName = user.getUsername(); 41 | String auth = userId + "," + userName; 42 | return generate(auth); 43 | } 44 | 45 | public String generate(String value) { 46 | String token = SecureUtil.md5(value + System.currentTimeMillis()); 47 | redisTemplate.opsForValue().set(Constant.AUTHENTICATION_TOKEN + token, value, Constant.TOKEN_EXPIRE, TimeUnit.SECONDS); 48 | return token; 49 | } 50 | 51 | public String getUserIdByToken(String token) { 52 | Object object = redisTemplate.opsForValue().get(Constant.AUTHENTICATION_TOKEN + token); 53 | if (object instanceof String) { 54 | String[] split = object.toString().split(","); 55 | return split[0]; 56 | } 57 | return null; 58 | } 59 | 60 | public void deleteToken(String token) { 61 | redisTemplate.delete(Constant.AUTHENTICATION_TOKEN + token); 62 | } 63 | 64 | 65 | public void generateAuth(String userId) { 66 | HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); 67 | generateAuth(request, userId); 68 | } 69 | 70 | public void generateAuth(HttpServletRequest request, String userId) { 71 | CustomUserDetailsService customUserDetailsService = SpringContextUtils.getBean(CustomUserDetailsService.class); 72 | UserDetails userDetails = customUserDetailsService.loadUserByUserId(userId); 73 | UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 74 | authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); 75 | SecurityContextHolder.getContext().setAuthentication(authentication); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/application/controller/XApplicationController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.application.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.crypto.SecureUtil; 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 | import com.baomidou.mybatisplus.core.metadata.IPage; 7 | import com.suke.czx.common.annotation.AuthIgnore; 8 | import com.suke.czx.common.annotation.ResourceAuth; 9 | import com.suke.czx.common.annotation.SysLog; 10 | import com.suke.czx.common.base.AbstractController; 11 | import com.suke.czx.common.utils.R; 12 | import com.suke.czx.modules.application.entity.XApplication; 13 | import com.suke.czx.modules.application.service.XApplicationService; 14 | import io.swagger.v3.oas.annotations.tags.Tag; 15 | import lombok.AllArgsConstructor; 16 | import org.springframework.web.bind.annotation.*; 17 | 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | 22 | /** 23 | * 应用服务 24 | * 25 | * @author czx 26 | * @email object_czx@163.com 27 | * @date 2025-08-15 16:34:08 28 | */ 29 | @RestController 30 | @AllArgsConstructor 31 | @RequestMapping("/application/manager") 32 | @Tag(name = "XApplicationController", description = "应用服务") 33 | public class XApplicationController extends AbstractController { 34 | private final XApplicationService xApplicationService; 35 | 36 | /** 37 | * 列表 38 | */ 39 | @GetMapping("/list") 40 | @ResourceAuth(value = "应用服务列表", module = "应用服务") 41 | public R list(@RequestParam Map params) { 42 | //查询列表数据 43 | QueryWrapper queryWrapper = new QueryWrapper<>(); 44 | final String keyword = mpPageConvert.getKeyword(params); 45 | if (StrUtil.isNotEmpty(keyword)) { 46 | 47 | } 48 | IPage listPage = xApplicationService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 49 | return R.ok().setData(listPage); 50 | } 51 | 52 | @AuthIgnore 53 | @GetMapping("/generateKey") 54 | public R generateKey() { 55 | String string = SecureUtil.md5(String.valueOf(System.currentTimeMillis())); 56 | return R.ok().setData(string); 57 | } 58 | 59 | @AuthIgnore 60 | @GetMapping("/select") 61 | public R select() { 62 | List list = xApplicationService.list(); 63 | return R.ok().setData(list); 64 | } 65 | 66 | /** 67 | * 新增应用服务 68 | */ 69 | @SysLog("新增应用服务数据") 70 | @PostMapping("/save") 71 | @ResourceAuth(value = "新增应用服务数据", module = "应用服务") 72 | public R save(@RequestBody XApplication param) { 73 | xApplicationService.save(param); 74 | return R.ok(); 75 | } 76 | 77 | 78 | /** 79 | * 修改 80 | */ 81 | @SysLog("修改应用服务数据") 82 | @PostMapping("/update") 83 | @ResourceAuth(value = "修改应用服务数据", module = "应用服务") 84 | public R update(@RequestBody XApplication param) { 85 | xApplicationService.updateById(param); 86 | return R.ok(); 87 | } 88 | 89 | 90 | /** 91 | * 删除 92 | */ 93 | @SysLog("删除应用服务数据") 94 | @PostMapping("/delete") 95 | @ResourceAuth(value = "删除应用服务数据", module = "应用服务") 96 | public R delete(@RequestBody XApplication param) { 97 | xApplicationService.removeById(param.getAppId()); 98 | return R.ok(); 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/msg/controller/XMessageServiceController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.msg.controller; 2 | 3 | import cn.hutool.core.map.MapUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 | import com.baomidou.mybatisplus.core.metadata.IPage; 7 | import com.suke.czx.common.annotation.ResourceAuth; 8 | import com.suke.czx.common.annotation.SysLog; 9 | import com.suke.czx.common.base.AbstractController; 10 | import com.suke.czx.common.utils.R; 11 | import com.suke.czx.modules.msg.entity.XMessageService; 12 | import com.suke.czx.modules.msg.service.XMessageServiceService; 13 | import io.swagger.v3.oas.annotations.tags.Tag; 14 | import lombok.AllArgsConstructor; 15 | import org.springframework.web.bind.annotation.*; 16 | 17 | import java.util.Map; 18 | 19 | 20 | /** 21 | * 短信服务 22 | * 23 | * @author czx 24 | * @email object_czx@163.com 25 | * @date 2025-08-15 17:51:27 26 | */ 27 | @RestController 28 | @AllArgsConstructor 29 | @RequestMapping("/msg/service") 30 | @Tag(name = "XMessageServiceController", description = "短信服务") 31 | public class XMessageServiceController extends AbstractController { 32 | private final XMessageServiceService xMessageServiceService; 33 | 34 | /** 35 | * 列表 36 | */ 37 | @GetMapping("/list") 38 | @ResourceAuth(value = "短信服务列表", module = "短信服务") 39 | public R list(@RequestParam Map params) { 40 | //查询列表数据 41 | QueryWrapper queryWrapper = new QueryWrapper<>(); 42 | final String keyword = mpPageConvert.getKeyword(params); 43 | if (StrUtil.isNotEmpty(keyword)) { 44 | queryWrapper.lambda().and(func -> func.like(XMessageService::getServiceName, keyword).or().eq(XMessageService::getDefaultTemplate, keyword)); 45 | } 46 | 47 | String tenancyId = MapUtil.getStr(params, "tenancyId"); 48 | if (StrUtil.isNotEmpty(tenancyId)) { 49 | queryWrapper.lambda().eq(XMessageService::getTenancyId, tenancyId); 50 | } 51 | 52 | IPage listPage = xMessageServiceService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 53 | this.fullTenancyInfo(listPage); 54 | return R.ok().setData(listPage); 55 | } 56 | 57 | 58 | /** 59 | * 新增短信服务 60 | */ 61 | @SysLog("新增短信服务数据") 62 | @PostMapping("/save") 63 | @ResourceAuth(value = "新增短信服务数据", module = "短信服务") 64 | public R save(@RequestBody XMessageService param) { 65 | xMessageServiceService.saveInfo(param); 66 | return R.ok(); 67 | } 68 | 69 | 70 | /** 71 | * 修改 72 | */ 73 | @SysLog("修改短信服务数据") 74 | @PostMapping("/update") 75 | @ResourceAuth(value = "修改短信服务数据", module = "短信服务") 76 | public R update(@RequestBody XMessageService param) { 77 | if (param.getServiceId() == null) { 78 | return R.error("服务ID为空"); 79 | } 80 | xMessageServiceService.updateInfo(param); 81 | return R.ok(); 82 | } 83 | 84 | 85 | /** 86 | * 删除 87 | */ 88 | @SysLog("删除短信服务数据") 89 | @PostMapping("/delete") 90 | @ResourceAuth(value = "删除短信服务数据", module = "短信服务") 91 | public R delete(@RequestBody XMessageService param) { 92 | if (param.getServiceId() == null) { 93 | return R.error("服务ID为空"); 94 | } 95 | xMessageServiceService.deleteInfo(param); 96 | return R.ok(); 97 | } 98 | 99 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/common/aspect/SysLogAspect.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.common.aspect; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.json.JSONObject; 5 | import cn.hutool.json.JSONUtil; 6 | import com.suke.czx.authentication.detail.CustomUserDetailsUser; 7 | import com.suke.czx.common.utils.HttpContextUtils; 8 | import com.suke.czx.common.utils.IPUtils; 9 | import com.suke.czx.modules.sys.entity.SysLog; 10 | import com.suke.czx.modules.sys.service.SysLogService; 11 | import jakarta.annotation.Resource; 12 | import jakarta.servlet.http.HttpServletRequest; 13 | import lombok.SneakyThrows; 14 | import org.aspectj.lang.ProceedingJoinPoint; 15 | import org.aspectj.lang.annotation.Around; 16 | import org.aspectj.lang.annotation.Aspect; 17 | import org.aspectj.lang.annotation.Pointcut; 18 | import org.aspectj.lang.reflect.MethodSignature; 19 | import org.springframework.security.core.context.SecurityContextHolder; 20 | import org.springframework.stereotype.Component; 21 | 22 | import java.lang.reflect.Method; 23 | import java.util.Date; 24 | 25 | 26 | /** 27 | * 系统日志,切面处理类 28 | * 29 | * @author czx 30 | * @email object_czx@163.com 31 | * @date 2017年3月8日 上午11:07:35 32 | */ 33 | @Aspect 34 | @Component 35 | public class SysLogAspect { 36 | 37 | @Resource 38 | private SysLogService sysLogService; 39 | 40 | @Pointcut("@annotation(com.suke.czx.common.annotation.SysLog)") 41 | public void logPointCut() { 42 | 43 | } 44 | 45 | @Around("logPointCut()") 46 | public Object around(ProceedingJoinPoint point) throws Throwable { 47 | long beginTime = System.currentTimeMillis(); 48 | //执行方法 49 | Object result = point.proceed(); 50 | //执行时长(毫秒) 51 | long time = System.currentTimeMillis() - beginTime; 52 | 53 | //保存日志 54 | saveSysLog(point, time); 55 | 56 | return result; 57 | } 58 | 59 | @SneakyThrows 60 | private void saveSysLog(ProceedingJoinPoint joinPoint, long time) { 61 | MethodSignature signature = (MethodSignature) joinPoint.getSignature(); 62 | Method method = signature.getMethod(); 63 | 64 | SysLog sysLog = new SysLog(); 65 | com.suke.czx.common.annotation.SysLog syslog = method.getAnnotation(com.suke.czx.common.annotation.SysLog.class); 66 | if (syslog != null) { 67 | //注解上的描述 68 | sysLog.setOperation(syslog.value()); 69 | } 70 | 71 | //请求的方法名 72 | String className = joinPoint.getTarget().getClass().getName(); 73 | String methodName = signature.getName(); 74 | sysLog.setMethod(className + "." + methodName + "()"); 75 | 76 | //请求的参数 77 | Object[] args = joinPoint.getArgs(); 78 | try { 79 | String params = JSONUtil.toJsonStr(args); 80 | sysLog.setParams(params); 81 | } catch (Exception ignored) { 82 | 83 | } 84 | 85 | //获取request 86 | HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); 87 | //设置IP地址 88 | sysLog.setIp(IPUtils.getIpAddr(request)); 89 | 90 | //用户名 91 | Object object = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 92 | if (object instanceof CustomUserDetailsUser user) { 93 | sysLog.setUsername(user.getUsername()); 94 | } 95 | 96 | sysLog.setTime(time); 97 | sysLog.setCreateDate(new Date()); 98 | //保存系统日志 99 | sysLogService.save(sysLog); 100 | } 101 | } -------------------------------------------------------------------------------- /src/main/java/com/suke/czx/modules/oss/controller/SysOssSettingController.java: -------------------------------------------------------------------------------- 1 | package com.suke.czx.modules.oss.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.suke.czx.common.annotation.ResourceAuth; 7 | import com.suke.czx.common.annotation.SysLog; 8 | import com.suke.czx.common.base.AbstractController; 9 | import com.suke.czx.common.utils.R; 10 | import com.suke.czx.modules.oss.entity.SysOssSetting; 11 | import com.suke.czx.modules.oss.service.SysOssSettingService; 12 | import io.swagger.v3.oas.annotations.tags.Tag; 13 | import lombok.AllArgsConstructor; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.Date; 17 | import java.util.Map; 18 | 19 | 20 | /** 21 | * 文件上传配置 22 | * 23 | * @author czx 24 | * @email object_czx@163.com 25 | * @date 2024-12-02 09:34:46 26 | */ 27 | @RestController 28 | @AllArgsConstructor 29 | @RequestMapping("/ossSetting/manager") 30 | @Tag(name = "SysOssSettingController", description = "文件上传配置") 31 | public class SysOssSettingController extends AbstractController { 32 | private final SysOssSettingService sysOssSettingService; 33 | 34 | /** 35 | * 列表 36 | */ 37 | @GetMapping("/list") 38 | @ResourceAuth(value = "文件上传配置列表", module = "文件上传配置") 39 | public R list(@RequestParam Map params) { 40 | //查询列表数据 41 | QueryWrapper queryWrapper = new QueryWrapper<>(); 42 | final String keyword = mpPageConvert.getKeyword(params); 43 | if (StrUtil.isNotEmpty(keyword)) { 44 | queryWrapper.lambda().like(SysOssSetting::getType, keyword); 45 | } 46 | IPage listPage = sysOssSettingService.page(mpPageConvert.pageParamConvert(params), queryWrapper); 47 | return R.ok().setData(listPage); 48 | } 49 | 50 | 51 | /** 52 | * 新增文件上传配置 53 | */ 54 | @SysLog("新增文件上传配置数据") 55 | @PostMapping("/save") 56 | @ResourceAuth(value = "新增文件上传配置数据", module = "文件上传配置") 57 | public R save(@RequestBody SysOssSetting param) { 58 | param.setStatus(0); 59 | param.setCreateDate(new Date()); 60 | sysOssSettingService.save(param); 61 | return R.ok(); 62 | } 63 | 64 | 65 | /** 66 | * 修改 67 | */ 68 | @SysLog("修改文件上传配置数据") 69 | @PostMapping("/update") 70 | @ResourceAuth(value = "修改文件上传配置数据", module = "文件上传配置") 71 | public R update(@RequestBody SysOssSetting param) { 72 | if (param.getId() == null) { 73 | return R.error("参数错误"); 74 | } 75 | param.setStatus(0); 76 | sysOssSettingService.updateById(param); 77 | return R.ok(); 78 | } 79 | 80 | @SysLog("设置默认文件上传配置数据") 81 | @PostMapping("/setDefault") 82 | @ResourceAuth(value = "设置默认文件上传配置数据", module = "文件上传配置") 83 | public R setDefault(@RequestBody SysOssSetting param) { 84 | if (param.getId() == null) { 85 | return R.error("参数错误"); 86 | } 87 | param.setStatus(1); 88 | sysOssSettingService.setDefault(param); 89 | return R.ok(); 90 | } 91 | 92 | /** 93 | * 删除 94 | */ 95 | @SysLog("删除文件上传配置数据") 96 | @PostMapping("/delete") 97 | @ResourceAuth(value = "删除文件上传配置数据", module = "文件上传配置") 98 | public R delete(@RequestBody SysOssSetting param) { 99 | sysOssSettingService.removeById(param.getId()); 100 | return R.ok(); 101 | } 102 | 103 | } 104 | --------------------------------------------------------------------------------