commit f1af70422ad9f76ac8f871b775551489c42ef246 Author: liuqingkun Date: Thu Feb 9 17:19:22 2023 +0800 project init diff --git a/src/main/java/org/springblade/common/constant/DictConstant.java b/src/main/java/org/springblade/common/constant/DictConstant.java new file mode 100644 index 0000000..fcee54a --- /dev/null +++ b/src/main/java/org/springblade/common/constant/DictConstant.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.common.constant; + +/** + * 字典常量. + * + * @author zhuangqian + */ +public interface DictConstant { + + String SEX_CODE = "sex"; + + String NOTICE_CODE = "notice"; + + String MENU_CATEGORY_CODE = "menu_category"; + + String BUTTON_FUNC_CODE = "button_func"; + + String YES_NO_CODE = "yes_no"; + +} diff --git a/src/main/java/org/springblade/common/event/ApiLogListener.java b/src/main/java/org/springblade/common/event/ApiLogListener.java new file mode 100644 index 0000000..bc23362 --- /dev/null +++ b/src/main/java/org/springblade/common/event/ApiLogListener.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ + +package org.springblade.common.event; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.launch.server.ServerInfo; +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.log.event.ApiLogEvent; +import org.springblade.core.log.model.LogApi; +import org.springblade.core.log.utils.LogAbstractUtil; +import org.springblade.modules.system.service.ILogService; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; + +import java.util.Map; + + +/** + * 异步监听日志事件 + * + * @author Chill + */ +@Slf4j +@AllArgsConstructor +public class ApiLogListener { + + private final ILogService logService; + private final ServerInfo serverInfo; + private final BladeProperties bladeProperties; + + + @Async + @Order + @EventListener(ApiLogEvent.class) + public void saveApiLog(ApiLogEvent event) { + Map source = (Map) event.getSource(); + LogApi logApi = (LogApi) source.get(EventConstant.EVENT_LOG); + LogAbstractUtil.addOtherInfoToLog(logApi, bladeProperties, serverInfo); + logService.saveApiLog(logApi); + } + +} diff --git a/src/main/java/org/springblade/common/event/UsualLogListener.java b/src/main/java/org/springblade/common/event/UsualLogListener.java new file mode 100644 index 0000000..c8c357b --- /dev/null +++ b/src/main/java/org/springblade/common/event/UsualLogListener.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.common.event; + + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.launch.props.BladeProperties; +import org.springblade.core.launch.server.ServerInfo; +import org.springblade.core.log.constant.EventConstant; +import org.springblade.core.log.event.UsualLogEvent; +import org.springblade.core.log.model.LogUsual; +import org.springblade.core.log.utils.LogAbstractUtil; +import org.springblade.modules.system.service.ILogService; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; + +import java.util.Map; + +/** + * 异步监听日志事件 + * + * @author Chill + */ +@Slf4j +@AllArgsConstructor +public class UsualLogListener { + + private final ILogService logService; + private final ServerInfo serverInfo; + private final BladeProperties bladeProperties; + + @Async + @Order + @EventListener(UsualLogEvent.class) + public void saveUsualLog(UsualLogEvent event) { + Map source = (Map) event.getSource(); + LogUsual logUsual = (LogUsual) source.get(EventConstant.EVENT_LOG); + LogAbstractUtil.addOtherInfoToLog(logUsual, bladeProperties, serverInfo); + logService.saveUsualLog(logUsual); + } + +} diff --git a/src/main/java/org/springblade/modules/resource/builder/oss/AliOssBuilder.java b/src/main/java/org/springblade/modules/resource/builder/oss/AliOssBuilder.java new file mode 100644 index 0000000..a6a1e24 --- /dev/null +++ b/src/main/java/org/springblade/modules/resource/builder/oss/AliOssBuilder.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.resource.builder.oss; + +import com.aliyun.oss.ClientConfiguration; +import com.aliyun.oss.OSSClient; +import com.aliyun.oss.common.auth.CredentialsProvider; +import com.aliyun.oss.common.auth.DefaultCredentialProvider; +import lombok.SneakyThrows; +import org.springblade.core.oss.OssTemplate; +import org.springblade.core.oss.AliossTemplate; +import org.springblade.core.oss.props.OssProperties; +import org.springblade.core.oss.rule.OssRule; +import org.springblade.modules.resource.entity.Oss; + +/** + * 阿里云存储构建类 + * + * @author Chill + */ +public class AliOssBuilder { + + @SneakyThrows + public static OssTemplate template(Oss oss, OssRule ossRule) { + // 创建配置类 + OssProperties ossProperties = new OssProperties(); + ossProperties.setEndpoint(oss.getEndpoint()); + ossProperties.setAccessKey(oss.getAccessKey()); + ossProperties.setSecretKey(oss.getSecretKey()); + ossProperties.setBucketName(oss.getBucketName()); + // 创建ClientConfiguration。ClientConfiguration是OSSClient的配置类,可配置代理、连接超时、最大连接数等参数。 + ClientConfiguration conf = new ClientConfiguration(); + // 设置OSSClient允许打开的最大HTTP连接数,默认为1024个。 + conf.setMaxConnections(1024); + // 设置Socket层传输数据的超时时间,默认为50000毫秒。 + conf.setSocketTimeout(50000); + // 设置建立连接的超时时间,默认为50000毫秒。 + conf.setConnectionTimeout(50000); + // 设置从连接池中获取连接的超时时间(单位:毫秒),默认不超时。 + conf.setConnectionRequestTimeout(1000); + // 设置连接空闲超时时间。超时则关闭连接,默认为60000毫秒。 + conf.setIdleConnectionTime(60000); + // 设置失败请求重试次数,默认为3次。 + conf.setMaxErrorRetry(5); + CredentialsProvider credentialsProvider = new DefaultCredentialProvider(ossProperties.getAccessKey(), ossProperties.getSecretKey()); + // 创建客户端 + OSSClient ossClient = new OSSClient(ossProperties.getEndpoint(), credentialsProvider, conf); + return new AliossTemplate(ossClient, ossProperties, ossRule); + } + +} diff --git a/src/main/java/org/springblade/modules/resource/builder/sms/AliSmsBuilder.java b/src/main/java/org/springblade/modules/resource/builder/sms/AliSmsBuilder.java new file mode 100644 index 0000000..b33312c --- /dev/null +++ b/src/main/java/org/springblade/modules/resource/builder/sms/AliSmsBuilder.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.resource.builder.sms; + +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.profile.DefaultProfile; +import com.aliyuncs.profile.IClientProfile; +import lombok.SneakyThrows; +import org.springblade.core.redis.cache.BladeRedis; +import org.springblade.core.sms.SmsTemplate; +import org.springblade.core.sms.AliSmsTemplate; +import org.springblade.core.sms.props.SmsProperties; +import org.springblade.modules.resource.entity.Sms; + +/** + * 阿里云短信构建类 + * + * @author Chill + */ +public class AliSmsBuilder { + + @SneakyThrows + public static SmsTemplate template(Sms sms, BladeRedis bladeRedis) { + SmsProperties smsProperties = new SmsProperties(); + smsProperties.setTemplateId(sms.getTemplateId()); + smsProperties.setAccessKey(sms.getAccessKey()); + smsProperties.setSecretKey(sms.getSecretKey()); + smsProperties.setRegionId(sms.getRegionId()); + smsProperties.setSignName(sms.getSignName()); + IClientProfile profile = DefaultProfile.getProfile(smsProperties.getRegionId(), smsProperties.getAccessKey(), smsProperties.getSecretKey()); + IAcsClient acsClient = new DefaultAcsClient(profile); + return new AliSmsTemplate(smsProperties, acsClient, bladeRedis); + } + +} diff --git a/src/main/java/org/springblade/modules/resource/builder/sms/YunpianSmsBuilder.java b/src/main/java/org/springblade/modules/resource/builder/sms/YunpianSmsBuilder.java new file mode 100644 index 0000000..7860077 --- /dev/null +++ b/src/main/java/org/springblade/modules/resource/builder/sms/YunpianSmsBuilder.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.resource.builder.sms; + +import com.yunpian.sdk.YunpianClient; +import lombok.SneakyThrows; +import org.springblade.core.redis.cache.BladeRedis; +import org.springblade.core.sms.SmsTemplate; +import org.springblade.core.sms.props.SmsProperties; +import org.springblade.core.sms.YunpianSmsTemplate; +import org.springblade.modules.resource.entity.Sms; + +/** + * 云片短信构建类 + * + * @author Chill + */ +public class YunpianSmsBuilder { + + @SneakyThrows + public static SmsTemplate template(Sms sms, BladeRedis bladeRedis) { + SmsProperties smsProperties = new SmsProperties(); + smsProperties.setTemplateId(sms.getTemplateId()); + smsProperties.setAccessKey(sms.getAccessKey()); + smsProperties.setSignName(sms.getSignName()); + YunpianClient client = new YunpianClient(smsProperties.getAccessKey()).init(); + return new YunpianSmsTemplate(smsProperties, client, bladeRedis); + } + +} diff --git a/src/main/java/org/springblade/modules/system/entity/UserOther.java b/src/main/java/org/springblade/modules/system/entity/UserOther.java new file mode 100644 index 0000000..8ec790a --- /dev/null +++ b/src/main/java/org/springblade/modules/system/entity/UserOther.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 实体类 + * + * @author Chill + */ +@Data +@TableName("blade_user_other") +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "UserOther对象", description = "UserOther对象") +public class UserOther extends Model { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @JsonSerialize(using = ToStringSerializer.class) + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户ID + */ + @JsonSerialize(using = ToStringSerializer.class) + @ApiModelProperty(value = "用户ID") + private Long userId; + + /** + * 用户拓展信息 + */ + @ApiModelProperty(value = "用户拓展信息") + private String userExt; + +} diff --git a/src/main/java/org/springblade/modules/system/entity/UserWeb.java b/src/main/java/org/springblade/modules/system/entity/UserWeb.java new file mode 100644 index 0000000..80ed941 --- /dev/null +++ b/src/main/java/org/springblade/modules/system/entity/UserWeb.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 实体类 + * + * @author Chill + */ +@Data +@TableName("blade_user_web") +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "UserWeb对象", description = "UserWeb对象") +public class UserWeb extends Model { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @JsonSerialize(using = ToStringSerializer.class) + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户ID + */ + @JsonSerialize(using = ToStringSerializer.class) + @ApiModelProperty(value = "用户ID") + private Long userId; + + /** + * 用户拓展信息 + */ + @ApiModelProperty(value = "用户拓展信息") + private String userExt; + +} diff --git a/src/main/java/org/springblade/modules/system/mapper/UserOauthMapper.xml b/src/main/java/org/springblade/modules/system/mapper/UserOauthMapper.xml new file mode 100644 index 0000000..cc36625 --- /dev/null +++ b/src/main/java/org/springblade/modules/system/mapper/UserOauthMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/springblade/modules/system/mapper/UserOtherMapper.java b/src/main/java/org/springblade/modules/system/mapper/UserOtherMapper.java new file mode 100644 index 0000000..f52a597 --- /dev/null +++ b/src/main/java/org/springblade/modules/system/mapper/UserOtherMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springblade.modules.system.entity.UserOther; + +/** + * Mapper 接口 + * + * @author Chill + */ +public interface UserOtherMapper extends BaseMapper { + + +} diff --git a/src/main/java/org/springblade/modules/system/mapper/UserOtherMapper.xml b/src/main/java/org/springblade/modules/system/mapper/UserOtherMapper.xml new file mode 100644 index 0000000..a790528 --- /dev/null +++ b/src/main/java/org/springblade/modules/system/mapper/UserOtherMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/org/springblade/modules/system/mapper/UserWebMapper.java b/src/main/java/org/springblade/modules/system/mapper/UserWebMapper.java new file mode 100644 index 0000000..5e1b224 --- /dev/null +++ b/src/main/java/org/springblade/modules/system/mapper/UserWebMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springblade.modules.system.entity.UserWeb; + +/** + * Mapper 接口 + * + * @author Chill + */ +public interface UserWebMapper extends BaseMapper { + + +} diff --git a/src/main/java/org/springblade/modules/system/mapper/UserWebMapper.xml b/src/main/java/org/springblade/modules/system/mapper/UserWebMapper.xml new file mode 100644 index 0000000..9a6d01b --- /dev/null +++ b/src/main/java/org/springblade/modules/system/mapper/UserWebMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/org/springblade/modules/system/service/impl/UserOauthServiceImpl.java b/src/main/java/org/springblade/modules/system/service/impl/UserOauthServiceImpl.java new file mode 100644 index 0000000..cb5a30a --- /dev/null +++ b/src/main/java/org/springblade/modules/system/service/impl/UserOauthServiceImpl.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.AllArgsConstructor; +import org.springblade.modules.system.entity.UserOauth; +import org.springblade.modules.system.mapper.UserOauthMapper; +import org.springblade.modules.system.service.IUserOauthService; +import org.springframework.stereotype.Service; + +/** + * 服务实现类 + * + * @author Chill + */ +@Service +@AllArgsConstructor +public class UserOauthServiceImpl extends ServiceImpl implements IUserOauthService { + +} diff --git a/src/main/java/org/springblade/modules/system/service/impl/UserSearchServiceImpl.java b/src/main/java/org/springblade/modules/system/service/impl/UserSearchServiceImpl.java new file mode 100644 index 0000000..3958b19 --- /dev/null +++ b/src/main/java/org/springblade/modules/system/service/impl/UserSearchServiceImpl.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.AllArgsConstructor; +import org.springblade.core.mp.base.BaseServiceImpl; +import org.springblade.modules.system.entity.User; +import org.springblade.modules.system.mapper.UserMapper; +import org.springblade.modules.system.service.IUserSearchService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 用户查询服务实现类 + * + * @author Chill + */ +@Service +@AllArgsConstructor +public class UserSearchServiceImpl extends BaseServiceImpl implements IUserSearchService { + + @Override + public List listByUser(List userId) { + return this.list(Wrappers.lambdaQuery().in(User::getId, userId)); + } + + @Override + public List listByDept(List deptId) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + deptId.forEach(id -> queryWrapper.like(User::getDeptId, id).or()); + return this.list(queryWrapper); + } + + @Override + public List listByPost(List postId) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + postId.forEach(id -> queryWrapper.like(User::getPostId, id).or()); + return this.list(queryWrapper); + } + + @Override + public List listByRole(List roleId) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + roleId.forEach(id -> queryWrapper.like(User::getRoleId, id).or()); + return this.list(queryWrapper); + } +} diff --git a/src/main/java/org/springblade/modules/system/service/impl/UserServiceImpl.java b/src/main/java/org/springblade/modules/system/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..6dc569d --- /dev/null +++ b/src/main/java/org/springblade/modules/system/service/impl/UserServiceImpl.java @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.AllArgsConstructor; +import org.springblade.common.cache.DictCache; +import org.springblade.common.cache.ParamCache; +import org.springblade.common.cache.SysCache; +import org.springblade.common.cache.UserCache; +import org.springblade.common.constant.CommonConstant; +import org.springblade.common.constant.TenantConstant; +import org.springblade.common.enums.DictEnum; +import org.springblade.core.log.exception.ServiceException; +import org.springblade.core.mp.base.BaseServiceImpl; +import org.springblade.core.mp.support.Condition; +import org.springblade.core.mp.support.Query; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tenant.BladeTenantProperties; +import org.springblade.core.tool.constant.BladeConstant; +import org.springblade.core.tool.jackson.JsonUtil; +import org.springblade.core.tool.support.Kv; +import org.springblade.core.tool.utils.*; +import org.springblade.modules.auth.enums.UserEnum; +import org.springblade.modules.system.entity.*; +import org.springblade.modules.system.excel.UserExcel; +import org.springblade.modules.system.mapper.UserMapper; +import org.springblade.modules.system.service.IRoleService; +import org.springblade.modules.system.service.IUserDeptService; +import org.springblade.modules.system.service.IUserOauthService; +import org.springblade.modules.system.service.IUserService; +import org.springblade.modules.system.vo.UserVO; +import org.springblade.modules.system.wrapper.UserWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static org.springblade.common.constant.CommonConstant.DEFAULT_PARAM_PASSWORD; + +/** + * 服务实现类 + * + * @author Chill + */ +@Service +@AllArgsConstructor +public class UserServiceImpl extends BaseServiceImpl implements IUserService { + private static final String GUEST_NAME = "guest"; + + private final IUserDeptService userDeptService; + private final IUserOauthService userOauthService; + private final IRoleService roleService; + private final BladeTenantProperties tenantProperties; + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean submit(User user) { + if (StringUtil.isBlank(user.getTenantId())) { + user.setTenantId(BladeConstant.ADMIN_TENANT_ID); + } + String tenantId = user.getTenantId(); + Tenant tenant = SysCache.getTenant(tenantId); + if (Func.isNotEmpty(tenant)) { + Integer accountNumber = tenant.getAccountNumber(); + if (tenantProperties.getLicense()) { + String licenseKey = tenant.getLicenseKey(); + String decrypt = DesUtil.decryptFormHex(licenseKey, TenantConstant.DES_KEY); + accountNumber = JsonUtil.parse(decrypt, Tenant.class).getAccountNumber(); + } + Long tenantCount = baseMapper.selectCount(Wrappers.query().lambda().eq(User::getTenantId, tenantId)); + if (accountNumber != null && accountNumber > 0 && accountNumber <= tenantCount) { + throw new ServiceException("当前租户已到最大账号额度!"); + } + } + if (Func.isNotEmpty(user.getPassword())) { + user.setPassword(DigestUtil.encrypt(user.getPassword())); + } + Long userCount = baseMapper.selectCount(Wrappers.query().lambda().eq(User::getTenantId, tenantId).eq(User::getAccount, user.getAccount())); + if (userCount > 0L && Func.isEmpty(user.getId())) { + throw new ServiceException(StringUtil.format("当前用户 [{}] 已存在!", user.getAccount())); + } + return save(user) && submitUserDept(user); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateUser(User user) { + String tenantId = user.getTenantId(); + Long userCount = baseMapper.selectCount( + Wrappers.query().lambda() + .eq(User::getTenantId, tenantId) + .eq(User::getAccount, user.getAccount()) + .notIn(User::getId, user.getId()) + ); + if (userCount > 0L) { + throw new ServiceException(StringUtil.format("当前用户 [{}] 已存在!", user.getAccount())); + } + return updateUserInfo(user) && submitUserDept(user); + } + + @Override + public boolean updateUserInfo(User user) { + user.setPassword(null); + return updateById(user); + } + + private boolean submitUserDept(User user) { + List deptIdList = Func.toLongList(user.getDeptId()); + List userDeptList = new ArrayList<>(); + deptIdList.forEach(deptId -> { + UserDept userDept = new UserDept(); + userDept.setUserId(user.getId()); + userDept.setDeptId(deptId); + userDeptList.add(userDept); + }); + userDeptService.remove(Wrappers.update().lambda().eq(UserDept::getUserId, user.getId())); + return userDeptService.saveBatch(userDeptList); + } + + @Override + public IPage selectUserPage(IPage page, User user, Long deptId, String tenantId) { + List deptIdList = SysCache.getDeptChildIds(deptId); + return page.setRecords(baseMapper.selectUserPage(page, user, deptIdList, tenantId)); + } + + @Override + public IPage selectUserSearch(UserVO user, Query query) { + LambdaQueryWrapper queryWrapper = Wrappers.query().lambda(); + String tenantId = AuthUtil.getTenantId(); + if (StringUtil.isNotBlank(tenantId)) { + queryWrapper.eq(User::getTenantId, tenantId); + } + if (StringUtil.isNotBlank(user.getName())) { + queryWrapper.like(User::getName, user.getName()); + } + if (StringUtil.isNotBlank(user.getDeptName())) { + String deptIds = SysCache.getDeptIdsByFuzzy(AuthUtil.getTenantId(), user.getDeptName()); + if (StringUtil.isNotBlank(deptIds)) { + queryWrapper.and(wrapper -> { + List ids = Func.toStrList(deptIds); + ids.forEach(id -> wrapper.like(User::getDeptId, id).or()); + }); + } + } + if (StringUtil.isNotBlank(user.getPostName())) { + String postIds = SysCache.getPostIdsByFuzzy(AuthUtil.getTenantId(), user.getPostName()); + if (StringUtil.isNotBlank(postIds)) { + queryWrapper.and(wrapper -> { + List ids = Func.toStrList(postIds); + ids.forEach(id -> wrapper.like(User::getPostId, id).or()); + }); + } + } + IPage pages = this.page(Condition.getPage(query), queryWrapper); + return UserWrapper.build().pageVO(pages); + } + + @Override + public User userByAccount(String tenantId, String account) { + return baseMapper.selectOne(Wrappers.query().lambda().eq(User::getTenantId, tenantId).eq(User::getAccount, account).eq(User::getIsDeleted, BladeConstant.DB_NOT_DELETED)); + } + + @Override + public UserInfo userInfo(Long userId) { + User user = baseMapper.selectById(userId); + return buildUserInfo(user); + } + + @Override + public UserInfo userInfo(String tenantId, String account, String password) { + User user = baseMapper.getUser(tenantId, account, password); + return buildUserInfo(user); + } + + @Override + public UserInfo userInfo(String tenantId, String account, String password, UserEnum userEnum) { + User user = baseMapper.getUser(tenantId, account, password); + return buildUserInfo(user, userEnum); + } + + private UserInfo buildUserInfo(User user) { + return buildUserInfo(user, UserEnum.WEB); + } + + private UserInfo buildUserInfo(User user, UserEnum userEnum) { + if (ObjectUtil.isEmpty(user)) { + return null; + } + UserInfo userInfo = new UserInfo(); + userInfo.setUser(user); + if (Func.isNotEmpty(user)) { + List roleAlias = roleService.getRoleAliases(user.getRoleId()); + userInfo.setRoles(roleAlias); + } + // 根据每个用户平台,建立对应的detail表,通过查询将结果集写入到detail字段 + Kv detail = Kv.create().set("type", userEnum.getName()); + if (userEnum == UserEnum.WEB) { + UserWeb userWeb = new UserWeb(); + UserWeb query = userWeb.selectOne(Wrappers.lambdaQuery().eq(UserWeb::getUserId, user.getId())); + if (ObjectUtil.isNotEmpty(query)) { + detail.set("ext", query.getUserExt()); + } + } else if (userEnum == UserEnum.APP) { + UserApp userApp = new UserApp(); + UserApp query = userApp.selectOne(Wrappers.lambdaQuery().eq(UserApp::getUserId, user.getId())); + if (ObjectUtil.isNotEmpty(query)) { + detail.set("ext", query.getUserExt()); + } + } else { + UserOther userOther = new UserOther(); + UserOther query = userOther.selectOne(Wrappers.lambdaQuery().eq(UserOther::getUserId, user.getId())); + if (ObjectUtil.isNotEmpty(query)) { + detail.set("ext", query.getUserExt()); + } + } + userInfo.setDetail(detail); + return userInfo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public UserInfo userInfo(UserOauth userOauth) { + UserOauth uo = userOauthService.getOne(Wrappers.query().lambda().eq(UserOauth::getUuid, userOauth.getUuid()).eq(UserOauth::getSource, userOauth.getSource())); + UserInfo userInfo; + if (Func.isNotEmpty(uo) && Func.isNotEmpty(uo.getUserId())) { + userInfo = this.userInfo(uo.getUserId()); + userInfo.setOauthId(Func.toStr(uo.getId())); + } else { + userInfo = new UserInfo(); + if (Func.isEmpty(uo)) { + userOauthService.save(userOauth); + userInfo.setOauthId(Func.toStr(userOauth.getId())); + } else { + userInfo.setOauthId(Func.toStr(uo.getId())); + } + User user = new User(); + user.setAccount(userOauth.getUsername()); + user.setTenantId(userOauth.getTenantId()); + userInfo.setUser(user); + userInfo.setRoles(Collections.singletonList(GUEST_NAME)); + } + return userInfo; + } + + @Override + public boolean grant(String userIds, String roleIds) { + User user = new User(); + user.setRoleId(roleIds); + return this.update(user, Wrappers.update().lambda().in(User::getId, Func.toLongList(userIds))); + } + + @Override + public boolean resetPassword(String userIds) { + User user = new User(); + user.setPassword(DigestUtil.encrypt(CommonConstant.DEFAULT_PASSWORD)); + user.setUpdateTime(DateUtil.now()); + return this.update(user, Wrappers.update().lambda().in(User::getId, Func.toLongList(userIds))); + } + + @Override + public boolean updatePassword(Long userId, String oldPassword, String newPassword, String newPassword1) { + User user = getById(userId); + if (!newPassword.equals(newPassword1)) { + throw new ServiceException("请输入正确的确认密码!"); + } + if (!user.getPassword().equals(DigestUtil.hex(oldPassword))) { + throw new ServiceException("原密码不正确!"); + } + return this.update(Wrappers.update().lambda().set(User::getPassword, DigestUtil.hex(newPassword)).eq(User::getId, userId)); + } + + @Override + public boolean removeUser(String userIds) { + if (Func.contains(Func.toLongArray(userIds), AuthUtil.getUserId())) { + throw new ServiceException("不能删除本账号!"); + } + return deleteLogic(Func.toLongList(userIds)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void importUser(List data, Boolean isCovered) { + data.forEach(userExcel -> { + User user = Objects.requireNonNull(BeanUtil.copy(userExcel, User.class)); + // 设置用户平台 + user.setUserType(Func.toInt(DictCache.getKey(DictEnum.USER_TYPE, userExcel.getUserTypeName()), 1)); + // 设置部门ID + user.setDeptId(Func.toStrWithEmpty(SysCache.getDeptIds(userExcel.getTenantId(), userExcel.getDeptName()), StringPool.EMPTY)); + // 设置岗位ID + user.setPostId(Func.toStrWithEmpty(SysCache.getPostIds(userExcel.getTenantId(), userExcel.getPostName()), StringPool.EMPTY)); + // 设置角色ID + user.setRoleId(Func.toStrWithEmpty(SysCache.getRoleIds(userExcel.getTenantId(), userExcel.getRoleName()), StringPool.EMPTY)); + // 设置租户ID + if (!AuthUtil.isAdministrator() || StringUtil.isBlank(user.getTenantId())) { + user.setTenantId(AuthUtil.getTenantId()); + } + // 覆盖数据 + if (isCovered) { + // 查询用户是否存在 + User oldUser = UserCache.getUser(userExcel.getTenantId(), userExcel.getAccount()); + if (oldUser != null && oldUser.getId() != null) { + user.setId(oldUser.getId()); + this.updateUser(user); + return; + } + } + // 获取默认密码配置 + String initPassword = ParamCache.getValue(DEFAULT_PARAM_PASSWORD); + user.setPassword(initPassword); + this.submit(user); + }); + } + + @Override + public List exportUser(Wrapper queryWrapper) { + List userList = baseMapper.exportUser(queryWrapper); + userList.forEach(user -> { + user.setUserTypeName(DictCache.getValue(DictEnum.USER_TYPE, user.getUserType())); + user.setRoleName(StringUtil.join(SysCache.getRoleNames(user.getRoleId()))); + user.setDeptName(StringUtil.join(SysCache.getDeptNames(user.getDeptId()))); + user.setPostName(StringUtil.join(SysCache.getPostNames(user.getPostId()))); + }); + return userList; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean registerGuest(User user, Long oauthId) { + Tenant tenant = SysCache.getTenant(user.getTenantId()); + if (tenant == null || tenant.getId() == null) { + throw new ServiceException("租户信息错误!"); + } + UserOauth userOauth = userOauthService.getById(oauthId); + if (userOauth == null || userOauth.getId() == null) { + throw new ServiceException("第三方登陆信息错误!"); + } + user.setRealName(user.getName()); + user.setAvatar(userOauth.getAvatar()); + user.setRoleId(StringPool.MINUS_ONE); + user.setDeptId(StringPool.MINUS_ONE); + user.setPostId(StringPool.MINUS_ONE); + boolean userTemp = this.submit(user); + userOauth.setUserId(user.getId()); + userOauth.setTenantId(user.getTenantId()); + boolean oauthTemp = userOauthService.updateById(userOauth); + return (userTemp && oauthTemp); + } + + @Override + public boolean updatePlatform(Long userId, Integer userType, String userExt) { + if (userType.equals(UserEnum.WEB.getCategory())) { + UserWeb userWeb = new UserWeb(); + UserWeb query = userWeb.selectOne(Wrappers.lambdaQuery().eq(UserWeb::getUserId, userId)); + if (ObjectUtil.isNotEmpty(query)) { + userWeb.setId(query.getId()); + } + userWeb.setUserId(userId); + userWeb.setUserExt(userExt); + return userWeb.insertOrUpdate(); + } else if (userType.equals(UserEnum.APP.getCategory())) { + UserApp userApp = new UserApp(); + UserApp query = userApp.selectOne(Wrappers.lambdaQuery().eq(UserApp::getUserId, userId)); + if (ObjectUtil.isNotEmpty(query)) { + userApp.setId(query.getId()); + } + userApp.setUserId(userId); + userApp.setUserExt(userExt); + return userApp.insertOrUpdate(); + } else { + UserOther userOther = new UserOther(); + UserOther query = userOther.selectOne(Wrappers.lambdaQuery().eq(UserOther::getUserId, userId)); + if (ObjectUtil.isNotEmpty(query)) { + userOther.setId(query.getId()); + } + userOther.setUserId(userId); + userOther.setUserExt(userExt); + return userOther.insertOrUpdate(); + } + } + + @Override + public UserVO platformDetail(User user) { + User detail = baseMapper.selectOne(Condition.getQueryWrapper(user)); + UserVO userVO = UserWrapper.build().entityVO(detail); + if (userVO.getUserType().equals(UserEnum.WEB.getCategory())) { + UserWeb userWeb = new UserWeb(); + UserWeb query = userWeb.selectOne(Wrappers.lambdaQuery().eq(UserWeb::getUserId, user.getId())); + if (ObjectUtil.isNotEmpty(query)) { + userVO.setUserExt(query.getUserExt()); + } + } else if (userVO.getUserType().equals(UserEnum.APP.getCategory())) { + UserApp userApp = new UserApp(); + UserApp query = userApp.selectOne(Wrappers.lambdaQuery().eq(UserApp::getUserId, user.getId())); + if (ObjectUtil.isNotEmpty(query)) { + userVO.setUserExt(query.getUserExt()); + } + } else { + UserOther userOther = new UserOther(); + UserOther query = userOther.selectOne(Wrappers.lambdaQuery().eq(UserOther::getUserId, user.getId())); + if (ObjectUtil.isNotEmpty(query)) { + userVO.setUserExt(query.getUserExt()); + } + } + return userVO; + } + +} diff --git a/src/main/java/org/springblade/modules/system/vo/UserVO.java b/src/main/java/org/springblade/modules/system/vo/UserVO.java new file mode 100644 index 0000000..3552e8e --- /dev/null +++ b/src/main/java/org/springblade/modules/system/vo/UserVO.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springblade.modules.system.entity.User; + +/** + * 视图实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "UserVO对象", description = "UserVO对象") +public class UserVO extends User { + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + /** + * 密码 + */ + @JsonIgnore + private String password; + + /** + * 租户名 + */ + private String tenantName; + + /** + * 用户平台名 + */ + private String userTypeName; + + /** + * 角色名 + */ + private String roleName; + + /** + * 部门名 + */ + private String deptName; + + /** + * 岗位名 + */ + private String postName; + + /** + * 性别 + */ + private String sexName; + + /** + * 拓展信息 + */ + private String userExt; +} diff --git a/src/main/java/org/springblade/modules/system/wrapper/UserWrapper.java b/src/main/java/org/springblade/modules/system/wrapper/UserWrapper.java new file mode 100644 index 0000000..d139a5b --- /dev/null +++ b/src/main/java/org/springblade/modules/system/wrapper/UserWrapper.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 庄骞 (smallchill@163.com) + */ +package org.springblade.modules.system.wrapper; + +import org.springblade.common.cache.DictCache; +import org.springblade.common.cache.SysCache; +import org.springblade.common.enums.DictEnum; +import org.springblade.core.mp.support.BaseEntityWrapper; +import org.springblade.core.tool.utils.BeanUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.modules.system.entity.Tenant; +import org.springblade.modules.system.entity.User; +import org.springblade.modules.system.vo.UserVO; + +import java.util.List; +import java.util.Objects; + +/** + * 包装类,返回视图层所需的字段 + * + * @author Chill + */ +public class UserWrapper extends BaseEntityWrapper { + + public static UserWrapper build() { + return new UserWrapper(); + } + + @Override + public UserVO entityVO(User user) { + UserVO userVO = Objects.requireNonNull(BeanUtil.copy(user, UserVO.class)); + Tenant tenant = SysCache.getTenant(user.getTenantId()); + List roleName = SysCache.getRoleNames(user.getRoleId()); + List deptName = SysCache.getDeptNames(user.getDeptId()); + List postName = SysCache.getPostNames(user.getPostId()); + userVO.setTenantName(tenant.getTenantName()); + userVO.setRoleName(Func.join(roleName)); + userVO.setDeptName(Func.join(deptName)); + userVO.setPostName(Func.join(postName)); + userVO.setSexName(DictCache.getValue(DictEnum.SEX, user.getSex())); + userVO.setUserTypeName(DictCache.getValue(DictEnum.USER_TYPE, user.getUserType())); + return userVO; + } + +}