Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into sms_temp_zzf_0127

This commit is contained in:
YunaiV
2021-03-22 23:42:59 +08:00
111 changed files with 3677 additions and 2580 deletions

View File

@@ -1,18 +1,35 @@
package cn.iocoder.dashboard.framework.jackson.config;
import cn.iocoder.dashboard.framework.jackson.deser.LocalDateTimeDeserializer;
import cn.iocoder.dashboard.framework.jackson.ser.LocalDateTimeSerializer;
import cn.iocoder.dashboard.util.json.JsonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
@Configuration
public class JacksonConfig {
@Bean
@SuppressWarnings("InstantiationOfUtilityClass")
public JsonUtils jsonUtils(ObjectMapper objectMapper) {
SimpleModule simpleModule = new SimpleModule();
/*
* 1. 新增Long类型序列化规则数值超过2^53-1在JS会出现精度丢失问题因此Long自动序列化为字符串类型
* 2. 新增LocalDateTime序列化、反序列化规则
*/
simpleModule
// .addSerializer(Long.class, ToStringSerializer.instance)
// .addSerializer(Long.TYPE, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
objectMapper.registerModules(simpleModule);
JsonUtils.init(objectMapper);
return new JsonUtils();
}
}

View File

@@ -0,0 +1,26 @@
package cn.iocoder.dashboard.framework.jackson.deser;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* LocalDateTime反序列化规则
* <p>
* 会将毫秒级时间戳反序列化为LocalDateTime
*/
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer();
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
}
}

View File

@@ -0,0 +1,24 @@
package cn.iocoder.dashboard.framework.jackson.ser;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* LocalDateTime序列化规则
* <p>
* 会将LocalDateTime序列化为毫秒级时间戳
*/
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer();
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
}

View File

@@ -81,7 +81,7 @@ public class ApiAccessLogFilter extends OncePerRequestFilter {
Map<String, String> queryString, String requestBody, Exception ex) {
// 处理用户信息
accessLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
accessLog.setUserType(WebFrameworkUtils.getUesrType(request));
accessLog.setUserType(WebFrameworkUtils.getUserType(request));
// 设置访问结果
CommonResult<?> result = WebFrameworkUtils.getCommonResult(request);
if (result != null) {

View File

@@ -1,14 +1,21 @@
package cn.iocoder.dashboard.framework.redis.config;
import cn.hutool.system.SystemUtil;
import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener;
import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.ObjectRecord;
import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.stream.StreamMessageListenerContainer;
import java.util.List;
@@ -19,6 +26,9 @@ import java.util.List;
@Slf4j
public class RedisConfig {
/**
* 创建 RedisTemplate Bean使用 JSON 序列化方式
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 创建 RedisTemplate 对象
@@ -27,11 +37,16 @@ public class RedisConfig {
template.setConnectionFactory(factory);
// 使用 String 序列化方式,序列化 KEY 。
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
template.setValueSerializer(RedisSerializer.json());
template.setHashValueSerializer(RedisSerializer.json());
return template;
}
/**
* 创建 Redis Pub/Sub 广播消费的容器
*/
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory,
List<AbstractChannelMessageListener<?>> listeners) {
@@ -48,4 +63,57 @@ public class RedisConfig {
return container;
}
/**
* 创建 Redis Stream 集群消费的容器
*
* Redis Stream 的 xreadgroup 命令https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html
*/
@Bean(initMethod = "start", destroyMethod = "stop")
public StreamMessageListenerContainer<String, ObjectRecord<String, String>> redisStreamMessageListenerContainer(RedisTemplate<String, Object> redisTemplate,
List<AbstractStreamMessageListener<?>> listeners) {
// 第一步,创建 StreamMessageListenerContainer 容器
// 创建 options 配置
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, String>> containerOptions =
StreamMessageListenerContainer.StreamMessageListenerContainerOptions.builder()
.batchSize(10) // 一次性最多拉取多少条消息
.targetType(String.class) // 目标类型。统一使用 String通过自己封装的 AbstractStreamMessageListener 去反序列化
.build();
// 创建 container 对象
StreamMessageListenerContainer<String, ObjectRecord<String, String>> container = StreamMessageListenerContainer.create(
redisTemplate.getRequiredConnectionFactory(), containerOptions);
// 第二步,注册监听器,消费对应的 Stream 主题
String consumerName = buildConsumerName();
// String consumerName = "110";
listeners.forEach(listener -> {
// 创建 listener 对应的消费者分组
try {
redisTemplate.opsForStream().createGroup(listener.getStreamKey(), listener.getGroup());
} catch (Exception ignore) {}
// 设置 listener 对应的 redisTemplate
listener.setRedisTemplate(redisTemplate);
// 创建 Consumer 对象
Consumer consumer = Consumer.from(listener.getGroup(), consumerName);
// 设置 Consumer 消费进度,以最小消费进度为准
StreamOffset<String> streamOffset = StreamOffset.create(listener.getStreamKey(), ReadOffset.lastConsumed());
// 设置 Consumer 监听
StreamMessageListenerContainer.StreamReadRequestBuilder<String> builder = StreamMessageListenerContainer.StreamReadRequest
.builder(streamOffset).consumer(consumer)
.autoAcknowledge(false) // 不自动 ack
.cancelOnError(throwable -> false); // 默认配置,发生异常就取消消费,显然不符合预期;因此,我们设置为 false
container.register(builder.build(), listener);
});
return container;
}
/**
* 构建消费者名字,使用本地 IP + 进程编号的方式。
* 参考自 RocketMQ clientId 的实现
*
* @return 消费者名字
*/
private static String buildConsumerName() {
return String.format("%s@%d", SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID());
}
}

View File

@@ -1,11 +1,10 @@
package cn.iocoder.dashboard.framework.redis.core.pubsub;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.TypeUtil;
import cn.iocoder.dashboard.util.json.JsonUtils;
import lombok.SneakyThrows;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.lang.reflect.Type;
@@ -62,21 +61,11 @@ public abstract class AbstractChannelMessageListener<T extends ChannelMessage> i
*/
@SuppressWarnings("unchecked")
private Class<T> getMessageClass() {
Class<?> targetClass = getClass();
while (targetClass.getSuperclass() != null) {
// 如果不是 AbstractMessageListener 父类,继续向上查找
if (targetClass.getSuperclass() != AbstractChannelMessageListener.class) {
targetClass = targetClass.getSuperclass();
continue;
}
// 如果是 AbstractMessageListener 父类,则解析泛型
Type[] types = ((ParameterizedTypeImpl) targetClass.getGenericSuperclass()).getActualTypeArguments();
if (ArrayUtil.isEmpty(types)) {
throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
}
return (Class<T>) types[0];
Type type = TypeUtil.getTypeArgument(getClass(), 0);
if (type == null) {
throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
}
throw new IllegalStateException(String.format("类型(%s) 找不到 AbstractMessageListener 父类", getClass().getName()));
return (Class<T>) type;
}
}

View File

@@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Redis Channel Message 接口
*
* @author 芋道源码
*/
public interface ChannelMessage {
@@ -12,7 +14,7 @@ public interface ChannelMessage {
*
* @return Channel
*/
@JsonIgnore // 必须序列化
@JsonIgnore // 避免序列化
String getChannel();
}

View File

@@ -0,0 +1,88 @@
package cn.iocoder.dashboard.framework.redis.core.stream;
import cn.hutool.core.util.TypeUtil;
import cn.iocoder.dashboard.util.json.JsonUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.stream.ObjectRecord;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.stream.StreamListener;
import java.lang.reflect.Type;
/**
* Redis Stream 监听器抽象类,用于实现集群消费
*
* @param <T> 消息类型。一定要填写噢,不然会报错
*
* @author 芋道源码
*/
public abstract class AbstractStreamMessageListener<T extends StreamMessage>
implements StreamListener<String, ObjectRecord<String, String>> {
/**
* 消息类型
*/
private final Class<T> messageType;
/**
* Redis Channel
*/
@Getter
private final String streamKey;
/**
* Redis 消费者分组,默认使用 spring.application.name 名字
*/
@Value("${spring.application.name}")
@Getter
private String group;
/**
*
*/
@Setter
private RedisTemplate<String, ?> redisTemplate;
@SneakyThrows
protected AbstractStreamMessageListener() {
this.messageType = getMessageClass();
this.streamKey = messageType.newInstance().getStreamKey();
}
@Override
public void onMessage(ObjectRecord<String, String> message) {
// 消费消息
T messageObj = JsonUtils.parseObject(message.getValue(), messageType);
this.onMessage(messageObj);
// ack 消息消费完成
redisTemplate.opsForStream().acknowledge(group, message);
// TODO 芋艿:需要额外考虑以下几个点:
// 1. 处理异常的情况
// 2. 发送日志;以及事务的结合
// 3. 消费日志;以及通用的幂等性
// 4. 消费失败的重试https://zhuanlan.zhihu.com/p/60501638
}
/**
* 处理消息
*
* @param message 消息
*/
public abstract void onMessage(T message);
/**
* 通过解析类上的泛型,获得消息类型
*
* @return 消息类型
*/
@SuppressWarnings("unchecked")
private Class<T> getMessageClass() {
Type type = TypeUtil.getTypeArgument(getClass(), 0);
if (type == null) {
throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
}
return (Class<T>) type;
}
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.dashboard.framework.redis.core.stream;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Redis Stream Message 接口
*
* @author 芋道源码
*/
public interface StreamMessage {
/**
* 获得 Redis Stream Key
*
* @return Channel
*/
@JsonIgnore // 避免序列化
String getStreamKey();
}

View File

@@ -1,7 +1,10 @@
package cn.iocoder.dashboard.framework.redis.core.util;
import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage;
import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
import cn.iocoder.dashboard.util.json.JsonUtils;
import org.springframework.data.redis.connection.stream.RecordId;
import org.springframework.data.redis.connection.stream.StreamRecords;
import org.springframework.data.redis.core.RedisTemplate;
/**
@@ -17,8 +20,21 @@ public class RedisMessageUtils {
* @param redisTemplate Redis 操作模板
* @param message 消息
*/
public static <T extends ChannelMessage> void sendChannelMessage(RedisTemplate<?, ?> redisTemplate, T message) {
public static <T extends ChannelMessage> void sendChannelMessage(RedisTemplate<?, ?> redisTemplate, T message) {
redisTemplate.convertAndSend(message.getChannel(), JsonUtils.toJsonString(message));
}
/**
* 发送 Redis 消息,基于 Redis Stream 实现
*
* @param redisTemplate Redis 操作模板
* @param message 消息
* @return 消息记录的编号对象
*/
public static <T extends StreamMessage> RecordId sendStreamMessage(RedisTemplate<String, ?> redisTemplate, T message) {
return redisTemplate.opsForStream().add(StreamRecords.newRecord()
.ofObject(JsonUtils.toJsonString(message)) // 设置内容
.withStreamKey(message.getStreamKey())); // 设置 stream key
}
}

View File

@@ -269,7 +269,7 @@ public class GlobalExceptionHandler {
private void initExceptionLog(ApiErrorLogCreateDTO errorLog, HttpServletRequest request, Throwable e) {
// 处理用户信息
errorLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
errorLog.setUserType(WebFrameworkUtils.getUesrType(request));
errorLog.setUserType(WebFrameworkUtils.getUserType(request));
// 设置异常字段
errorLog.setExceptionName(e.getClass().getName());
errorLog.setExceptionMessage(ExceptionUtil.getMessage(e));

View File

@@ -31,7 +31,7 @@ public class WebFrameworkUtils {
return (Long) request.getAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_ID);
}
public static Integer getUesrType(HttpServletRequest request) {
public static Integer getUserType(HttpServletRequest request) {
return UserTypeEnum.ADMIN.getValue(); // TODO 芋艿:等后续优化
}

View File

@@ -19,6 +19,7 @@ import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import cn.iocoder.dashboard.util.collection.SetUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -34,6 +35,7 @@ import static cn.iocoder.dashboard.util.servlet.ServletUtils.getUserAgent;
@Api(tags = "认证")
@RestController
@RequestMapping("/")
@Validated
public class SysAuthController {
@Resource
@@ -45,8 +47,8 @@ public class SysAuthController {
@Resource
private SysPermissionService permissionService;
@ApiOperation("使用账号密码登录")
@PostMapping("/login")
@ApiOperation("使用账号密码登录")
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) {
String token = authService.login(reqVO, getClientIP(), getUserAgent());
@@ -54,8 +56,8 @@ public class SysAuthController {
return success(SysAuthLoginRespVO.builder().token(token).build());
}
@ApiOperation("获取登陆用户的权限信息")
@GetMapping("/get-permission-info")
@ApiOperation("获取登陆用户的权限信息")
public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() {
// 获得用户信息
SysUserDO user = userService.getUser(getLoginUserId());
@@ -63,9 +65,9 @@ public class SysAuthController {
return null;
}
// 获得角色列表
List<SysRoleDO> roleList = roleService.listRolesFromCache(getLoginUserRoleIds());
List<SysRoleDO> roleList = roleService.getRolesFromCache(getLoginUserRoleIds());
// 获得菜单列表
List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(
List<SysMenuDO> menuList = permissionService.getRoleMenusFromCache(
getLoginUserRoleIds(), // 注意,基于登陆的角色,因为后续的权限判断也是基于它
SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()),
SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
@@ -73,11 +75,11 @@ public class SysAuthController {
return success(SysAuthConvert.INSTANCE.convert(user, roleList, menuList));
}
@ApiOperation("获得登陆用户的菜单列表")
@GetMapping("list-menus")
public CommonResult<List<SysAuthMenuRespVO>> listMenus() {
@ApiOperation("获得登陆用户的菜单列表")
public CommonResult<List<SysAuthMenuRespVO>> getMenus() {
// 获得用户拥有的菜单列表
List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(
List<SysMenuDO> menuList = permissionService.getRoleMenusFromCache(
getLoginUserRoleIds(), // 注意,基于登陆的角色,因为后续的权限判断也是基于它
SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型
SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的

View File

@@ -39,9 +39,9 @@ public class SysUserSessionController {
@Resource
private SysDeptService deptService;
@GetMapping("/page")
@ApiOperation("获得 Session 分页列表")
@PreAuthorize("@ss.hasPermission('system:user-session:page')")
@GetMapping("/page")
public CommonResult<PageResult<SysUserSessionPageItemRespVO>> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) {
// 获得 Session 分页
PageResult<SysUserSessionDO> pageResult = userSessionService.getUserSessionPage(reqVO);
@@ -66,12 +66,12 @@ public class SysUserSessionController {
return success(new PageResult<>(sessionList, pageResult.getTotal()));
}
@ApiOperation("删除 Session")
@PreAuthorize("@ss.hasPermission('system:user-session:delete')")
@DeleteMapping("/delete")
@ApiOperation("删除 Session")
@ApiImplicitParam(name = "id", value = "Session 编号", required = true, dataTypeClass = String.class,
example = "fe50b9f6-d177-44b1-8da9-72ea34f63db7")
public CommonResult<Boolean> delete(@RequestParam("id") String id) {
@PreAuthorize("@ss.hasPermission('system:user-session:delete')")
public CommonResult<Boolean> deleteUserSession(@RequestParam("id") String id) {
userSessionService.deleteUserSession(id);
return success(true);
}

View File

@@ -9,10 +9,12 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Comparator;
import java.util.List;
@@ -21,65 +23,64 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@Api(tags = "部门")
@RestController
@RequestMapping("/system/dept")
@Validated
public class SysDeptController {
@Resource
private SysDeptService deptService;
@ApiOperation("获取部门列表")
// @PreAuthorize("@ss.hasPermi('system:dept:list')")
@PostMapping("create")
@ApiOperation("创建部门")
@PreAuthorize("@ss.hasPermission('system:dept:create')")
public CommonResult<Long> createDept(@Valid @RequestBody SysDeptCreateReqVO reqVO) {
Long deptId = deptService.createDept(reqVO);
return success(deptId);
}
@PutMapping("update")
@ApiOperation("更新部门")
@PreAuthorize("@ss.hasPermission('system:dept:update')")
public CommonResult<Boolean> updateDept(@Valid @RequestBody SysDeptUpdateReqVO reqVO) {
deptService.updateDept(reqVO);
return success(true);
}
@DeleteMapping("delete")
@ApiOperation("删除部门")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('system:dept:delete')")
public CommonResult<Boolean> deleteDept(@RequestParam("id") Long id) {
deptService.deleteDept(id);
return success(true);
}
@GetMapping("/list")
@ApiOperation("获取部门列表")
@PreAuthorize("@ss.hasPermission('system:dept:query')")
public CommonResult<List<SysDeptRespVO>> listDepts(SysDeptListReqVO reqVO) {
List<SysDeptDO> list = deptService.listDepts(reqVO);
List<SysDeptDO> list = deptService.getSimpleDepts(reqVO);
list.sort(Comparator.comparing(SysDeptDO::getSort));
return success(SysDeptConvert.INSTANCE.convertList(list));
}
@ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项")
@GetMapping("/list-all-simple")
public CommonResult<List<SysDeptSimpleRespVO>> listSimpleDepts() {
@ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项")
public CommonResult<List<SysDeptSimpleRespVO>> getSimpleDepts() {
// 获得部门列表,只要开启状态的
SysDeptListReqVO reqVO = new SysDeptListReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
List<SysDeptDO> list = deptService.listDepts(reqVO);
List<SysDeptDO> list = deptService.getSimpleDepts(reqVO);
// 排序后,返回给前端
list.sort(Comparator.comparing(SysDeptDO::getSort));
return success(SysDeptConvert.INSTANCE.convertList02(list));
}
@GetMapping("/get")
@ApiOperation("获得部门信息")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermi('system:dept:query')")
@GetMapping("/get")
@PreAuthorize("@ss.hasPermission('system:dept:query')")
public CommonResult<SysDeptRespVO> getDept(@RequestParam("id") Long id) {
return success(SysDeptConvert.INSTANCE.convert(deptService.getDept(id)));
}
@ApiOperation("新增部门")
@PostMapping("create")
// @PreAuthorize("@ss.hasPermi('system:dept:add')")
// @Log(title = "部门管理", businessType = BusinessType.INSERT)
public CommonResult<Long> createDept(@Validated @RequestBody SysDeptCreateReqVO reqVO) {
Long deptId = deptService.createDept(reqVO);
return success(deptId);
}
@ApiOperation("修改部门")
@PostMapping("update")
// @PreAuthorize("@ss.hasPermi('system:dept:edit')")
// @Log(title = "部门管理", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updateDept(@Validated @RequestBody SysDeptUpdateReqVO reqVO) {
deptService.updateDept(reqVO);
return success(true);
}
@ApiOperation("删除部门")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PostMapping("delete")
// @PreAuthorize("@ss.hasPermi('system:dept:remove')")
// @Log(title = "部门管理", businessType = BusinessType.DELETE)
public CommonResult<Boolean> deleteDept(@RequestParam("id") Long id) {
deptService.deleteDept(id);
return success(true);
}
}

View File

@@ -4,6 +4,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.*;
import cn.iocoder.dashboard.modules.system.convert.dept.SysPostConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
@@ -11,88 +12,88 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "岗位")
@RestController
@RequestMapping("/system/post")
@Valid
public class SysPostController {
@Resource
private SysPostService postService;
@ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项")
@GetMapping("/list-all-simple")
public CommonResult<List<SysPostSimpleRespVO>> listSimplePosts() {
// 获得岗位列表,只要开启状态的
List<SysPostDO> list = postService.listPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
// 排序后,返回给前端
list.sort(Comparator.comparing(SysPostDO::getSort));
return success(SysPostConvert.INSTANCE.convertList02(list));
}
@ApiOperation("获得岗位分页列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:post:list')")
public CommonResult<PageResult<SysPostRespVO>> pagePosts(@Validated SysPostPageReqVO reqVO) {
return success(SysPostConvert.INSTANCE.convertPage(postService.pagePosts(reqVO)));
}
@ApiOperation("新增岗位")
@PostMapping("/create")
// @PreAuthorize("@ss.hasPermi('system:post:add')")
// @Log(title = "岗位管理", businessType = BusinessType.INSERT)
public CommonResult<Long> createPost(@Validated @RequestBody SysPostCreateReqVO reqVO) {
@ApiOperation("创建岗位")
@PreAuthorize("@ss.hasPermission('system:post:create')")
public CommonResult<Long> createPost(@Valid @RequestBody SysPostCreateReqVO reqVO) {
Long postId = postService.createPost(reqVO);
return success(postId);
}
@PutMapping("/update")
@ApiOperation("修改岗位")
@PostMapping("/update")
// @PreAuthorize("@ss.hasPermi('system:post:edit')")
// @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updatePost(@Validated @RequestBody SysPostUpdateReqVO reqVO) {
@PreAuthorize("@ss.hasPermission('system:post:update')")
public CommonResult<Boolean> updatePost(@Valid @RequestBody SysPostUpdateReqVO reqVO) {
postService.updatePost(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除岗位")
@PostMapping("/delete")
// @PreAuthorize("@ss.hasPermi('system:post:remove')")
// @Log(title = "岗位管理", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermission('system:post:delete')")
public CommonResult<Boolean> deletePost(@RequestParam("id") Long id) {
postService.deletePost(id);
return success(true);
}
@GetMapping(value = "/get")
@ApiOperation("获得岗位信息")
@ApiImplicitParam(name = "id", value = "岗位编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermi('system:post:query')")
@GetMapping(value = "/get")
@PreAuthorize("@ss.hasPermission('system:post:query')")
public CommonResult<SysPostRespVO> getPost(@RequestParam("id") Long id) {
return success(SysPostConvert.INSTANCE.convert(postService.getPost(id)));
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项")
public CommonResult<List<SysPostSimpleRespVO>> getSimplePosts() {
// 获得岗位列表,只要开启状态的
List<SysPostDO> list = postService.getPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
// 排序后,返回给前端
list.sort(Comparator.comparing(SysPostDO::getSort));
return success(SysPostConvert.INSTANCE.convertList02(list));
}
@GetMapping("/page")
@ApiOperation("获得岗位分页列表")
@PreAuthorize("@ss.hasPermission('system:post:query')")
public CommonResult<PageResult<SysPostRespVO>> getPostPage(@Validated SysPostPageReqVO reqVO) {
return success(SysPostConvert.INSTANCE.convertPage(postService.getPostPage(reqVO)));
}
@GetMapping("/export")
@ApiOperation("岗位管理")
// @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
// @PreAuthorize("@ss.hasPermi('system:post:export')")
@PreAuthorize("@ss.hasPermission('system:post:export')")
@OperateLog(type = EXPORT)
public void export(HttpServletResponse response, @Validated SysPostExportReqVO reqVO) throws IOException {
List<SysPostDO> posts = postService.listPosts(reqVO);
List<SysPostExcelVO> excelDataList = SysPostConvert.INSTANCE.convertList03(posts);
List<SysPostDO> posts = postService.getPosts(reqVO);
List<SysPostExcelVO> data = SysPostConvert.INSTANCE.convertList03(posts);
// 输出
ExcelUtils.write(response, "岗位数据.xls", "岗位列表",
SysPostExcelVO.class, excelDataList);
ExcelUtils.write(response, "岗位数据.xls", "岗位列表", SysPostExcelVO.class, data);
}
}

View File

@@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dict;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.*;
import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO;
@@ -10,84 +11,85 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "字典数据")
@RestController
@RequestMapping("/system/dict-data")
@Validated
public class SysDictDataController {
@Resource
private SysDictDataService dictDataService;
@ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地")
@GetMapping("/list-all-simple")
// 无需添加权限认证,因为前端全局都需要
public CommonResult<List<SysDictDataSimpleVO>> listSimpleDictDatas() {
List<SysDictDataDO> list = dictDataService.getDictDataList();
return success(SysDictDataConvert.INSTANCE.convertList(list));
}
@ApiOperation("/获得字典类型的分页列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:dict:list')")
public CommonResult<PageResult<SysDictDataRespVO>> pageDictTypes(@Validated SysDictDataPageReqVO reqVO) {
return success(SysDictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO)));
}
@ApiOperation("/查询字典数据详细")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@GetMapping(value = "/get")
// @PreAuthorize("@ss.hasPermi('system:dict:query')")
public CommonResult<SysDictDataRespVO> getDictData(@RequestParam("id") Long id) {
return success(SysDictDataConvert.INSTANCE.convert(dictDataService.getDictData(id)));
}
@ApiOperation("新增字典数据")
@PostMapping("/create")
// @PreAuthorize("@ss.hasPermi('system:dict:add')")
// @Log(title = "字典数据", businessData = BusinessData.INSERT)
public CommonResult<Long> createDictData(@Validated @RequestBody SysDictDataCreateReqVO reqVO) {
@ApiOperation("新增字典数据")
@PreAuthorize("@ss.hasPermission('system:dict:create')")
public CommonResult<Long> createDictData(@Valid @RequestBody SysDictDataCreateReqVO reqVO) {
Long dictDataId = dictDataService.createDictData(reqVO);
return success(dictDataId);
}
@PutMapping("update")
@ApiOperation("修改字典数据")
@PostMapping("update")
// @PreAuthorize("@ss.hasPermi('system:dict:edit')")
// @Log(title = "字典数据", businessData = BusinessData.UPDATE)
public CommonResult<Boolean> updateDictData(@Validated @RequestBody SysDictDataUpdateReqVO reqVO) {
@PreAuthorize("@ss.hasPermission('system:dict:update')")
public CommonResult<Boolean> updateDictData(@Valid @RequestBody SysDictDataUpdateReqVO reqVO) {
dictDataService.updateDictData(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除字典数据")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PostMapping("/delete")
// @PreAuthorize("@ss.hasPermi('system:dict:remove')")
@PreAuthorize("@ss.hasPermission('system:dict:delete')")
public CommonResult<Boolean> deleteDictData(Long id) {
dictDataService.deleteDictData(id);
return success(true);
}
@ApiOperation("导出字典数据")
@GetMapping("/list-all-simple")
@ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地")
// 无需添加权限认证,因为前端全局都需要
public CommonResult<List<SysDictDataSimpleVO>> getSimpleDictDatas() {
List<SysDictDataDO> list = dictDataService.getDictDatas();
return success(SysDictDataConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("/获得字典类型的分页列表")
@PreAuthorize("@ss.hasPermission('system:dict:query')")
public CommonResult<PageResult<SysDictDataRespVO>> getDictTypePage(@Valid SysDictDataPageReqVO reqVO) {
return success(SysDictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO)));
}
@GetMapping(value = "/get")
@ApiOperation("/查询字典数据详细")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('system:dict:query')")
public CommonResult<SysDictDataRespVO> getDictData(@RequestParam("id") Long id) {
return success(SysDictDataConvert.INSTANCE.convert(dictDataService.getDictData(id)));
}
@GetMapping("/export")
// @Log(title = "字典类型", businessType = BusinessType.EXPORT)
// @PreAuthorize("@ss.hasPermi('system:dict:export')")
public void export(HttpServletResponse response, @Validated SysDictDataExportReqVO reqVO) throws IOException {
List<SysDictDataDO> list = dictDataService.getDictDataList(reqVO);
List<SysDictDataExcelVO> excelDataList = SysDictDataConvert.INSTANCE.convertList02(list);
@ApiOperation("导出字典数据")
@PreAuthorize("@ss.hasPermission('system:dict:export')")
@OperateLog(type = EXPORT)
public void export(HttpServletResponse response, @Valid SysDictDataExportReqVO reqVO) throws IOException {
List<SysDictDataDO> list = dictDataService.getDictDatas(reqVO);
List<SysDictDataExcelVO> data = SysDictDataConvert.INSTANCE.convertList02(list);
// 输出
ExcelUtils.write(response, "字典数据.xls", "数据列表",
SysDictDataExcelVO.class, excelDataList);
ExcelUtils.write(response, "字典数据.xls", "数据列表", SysDictDataExcelVO.class, data);
}
}

View File

@@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dict;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.modules.system.controller.dict.vo.type.*;
import cn.iocoder.dashboard.modules.system.convert.dict.SysDictTypeConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictTypeDO;
@@ -10,67 +11,68 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "字典类型")
@RestController
@RequestMapping("/system/dict-type")
@Validated
public class SysDictTypeController {
@Resource
private SysDictTypeService dictTypeService;
@PostMapping("/create")
@ApiOperation("创建字典类型")
@PreAuthorize("@ss.hasPermission('system:dict:create')")
public CommonResult<Long> createDictType(@Valid @RequestBody SysDictTypeCreateReqVO reqVO) {
Long dictTypeId = dictTypeService.createDictType(reqVO);
return success(dictTypeId);
}
@PostMapping("update")
@ApiOperation("修改字典类型")
@PreAuthorize("@ss.hasPermission('system:dict:update')")
public CommonResult<Boolean> updateDictType(@Valid @RequestBody SysDictTypeUpdateReqVO reqVO) {
dictTypeService.updateDictType(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除字典类型")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('system:dict:delete')")
public CommonResult<Boolean> deleteDictType(Long id) {
dictTypeService.deleteDictType(id);
return success(true);
}
@ApiOperation("/获得字典类型的分页列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:dict:list')")
public CommonResult<PageResult<SysDictTypeRespVO>> pageDictTypes(@Validated SysDictTypePageReqVO reqVO) {
@PreAuthorize("@ss.hasPermission('system:dict:quey')")
public CommonResult<PageResult<SysDictTypeRespVO>> pageDictTypes(@Valid SysDictTypePageReqVO reqVO) {
return success(SysDictTypeConvert.INSTANCE.convertPage(dictTypeService.getDictTypePage(reqVO)));
}
@ApiOperation("/查询字典类型详细")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@GetMapping(value = "/get")
// @PreAuthorize("@ss.hasPermi('system:dict:query')")
@PreAuthorize("@ss.hasPermission('system:dict:quey')")
public CommonResult<SysDictTypeRespVO> getDictType(@RequestParam("id") Long id) {
return success(SysDictTypeConvert.INSTANCE.convert(dictTypeService.getDictType(id)));
}
@ApiOperation("新增字典类型")
@PostMapping("/create")
// @PreAuthorize("@ss.hasPermi('system:dict:add')")
// @Log(title = "字典类型", businessType = BusinessType.INSERT)
public CommonResult<Long> createDictType(@Validated @RequestBody SysDictTypeCreateReqVO reqVO) {
Long dictTypeId = dictTypeService.createDictType(reqVO);
return success(dictTypeId);
}
@ApiOperation("修改字典类型")
@PostMapping("update")
// @PreAuthorize("@ss.hasPermi('system:dict:edit')")
// @Log(title = "字典类型", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updateDictType(@Validated @RequestBody SysDictTypeUpdateReqVO reqVO) {
dictTypeService.updateDictType(reqVO);
return success(true);
}
@ApiOperation("删除字典类型")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PostMapping("/delete")
// @PreAuthorize("@ss.hasPermi('system:dict:remove')")
public CommonResult<Boolean> deleteDictType(Long id) {
dictTypeService.deleteDictType(id);
return success(true);
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获得全部字典类型列表", notes = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项")
// 无需添加权限认证,因为前端全局都需要
@@ -81,14 +83,13 @@ public class SysDictTypeController {
@ApiOperation("导出数据类型")
@GetMapping("/export")
// @Log(title = "字典类型", businessType = BusinessType.EXPORT)
// @PreAuthorize("@ss.hasPermi('system:dict:export')")
public void export(HttpServletResponse response, @Validated SysDictTypeExportReqVO reqVO) throws IOException {
@PreAuthorize("@ss.hasPermission('system:dict:quey')")
@OperateLog(type = EXPORT)
public void export(HttpServletResponse response, @Valid SysDictTypeExportReqVO reqVO) throws IOException {
List<SysDictTypeDO> list = dictTypeService.getDictTypeList(reqVO);
List<SysDictTypeExcelVO> excelTypeList = SysDictTypeConvert.INSTANCE.convertList02(list);
List<SysDictTypeExcelVO> data = SysDictTypeConvert.INSTANCE.convertList02(list);
// 输出
ExcelUtils.write(response, "字典类型.xls", "类型列表",
SysDictTypeExcelVO.class, excelTypeList);
ExcelUtils.write(response, "字典类型.xls", "类型列表", SysDictTypeExcelVO.class, data);
}
}

View File

@@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.logger;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogExcelVO;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogExportReqVO;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogPageReqVO;
@@ -12,6 +13,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysLoginLogDO;
import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -19,36 +21,39 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "登陆日志")
@RestController
@RequestMapping("/system/login-log")
@Validated
public class SysLoginLogController {
@Resource
private SysLoginLogService loginLogService;
@ApiOperation("获得登陆日志分页列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:login-log:query')")
public CommonResult<PageResult<SysLoginLogRespVO>> getLoginLogPage(@Validated SysLoginLogPageReqVO reqVO) {
@ApiOperation("获得登陆日志分页列表")
@PreAuthorize("@ss.hasPermission('system:login-log:query')")
public CommonResult<PageResult<SysLoginLogRespVO>> getLoginLogPage(@Valid SysLoginLogPageReqVO reqVO) {
PageResult<SysLoginLogDO> page = loginLogService.getLoginLogPage(reqVO);
return CommonResult.success(SysLoginLogConvert.INSTANCE.convertPage(page));
}
@ApiOperation("导出登陆日志 Excel")
@GetMapping("/export")
// @Log(title = "登录日志", businessType = BusinessType.EXPORT)
// @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
public void exportLoginLog(HttpServletResponse response, @Validated SysLoginLogExportReqVO reqVO) throws IOException {
@ApiOperation("导出登陆日志 Excel")
@PreAuthorize("@ss.hasPermission('system:login-log:export')")
@OperateLog(type = EXPORT)
public void exportLoginLog(HttpServletResponse response, @Valid SysLoginLogExportReqVO reqVO) throws IOException {
List<SysLoginLogDO> list = loginLogService.getLoginLogList(reqVO);
// 拼接数据
List<SysLoginLogExcelVO> excelDataList = SysLoginLogConvert.INSTANCE.convertList(list);
List<SysLoginLogExcelVO> data = SysLoginLogConvert.INSTANCE.convertList(list);
// 输出
ExcelUtils.write(response, "登陆日志.xls", "数据列表",
SysLoginLogExcelVO.class, excelDataList);
ExcelUtils.write(response, "登陆日志.xls", "数据列表", SysLoginLogExcelVO.class, data);
}
}

View File

@@ -4,8 +4,6 @@ import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
import cn.iocoder.dashboard.framework.logger.operatelog.core.util.OperateLogUtils;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogExcelVO;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogExportReqVO;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogPageReqVO;
@@ -19,6 +17,7 @@ import cn.iocoder.dashboard.util.collection.CollectionUtils;
import cn.iocoder.dashboard.util.collection.MapUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -38,33 +38,19 @@ import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.Operat
@Api(tags = "操作日志")
@RestController
@RequestMapping("/system/operate-log")
@Validated
public class SysOperateLogController {
@Resource
private SysOperateLogService operateLogService;
@Resource
private SysUserService userService;
@ApiOperation("示例")
@OperateLog(type = OperateTypeEnum.OTHER)
@GetMapping("/demo")
public CommonResult<Boolean> demo() {
// 这里可以调用业务逻辑
// 补全操作日志的明细
OperateLogUtils.setContent("将编号 1 的数据xxx 字段修改成了 yyyy");
OperateLogUtils.addExt("orderId", 1);
// 响应
return success(true);
}
@ApiOperation("查看操作日志分页列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:operate-log:query')")
public CommonResult<PageResult<SysOperateLogRespVO>> pageOperateLog(@Validated SysOperateLogPageReqVO reqVO) {
PageResult<SysOperateLogDO> pageResult = operateLogService.pageOperateLog(reqVO);
@ApiOperation("查看操作日志分页列表")
@PreAuthorize("@ss.hasPermission('system:operate-log:query')")
public CommonResult<PageResult<SysOperateLogRespVO>> pageOperateLog(@Valid SysOperateLogPageReqVO reqVO) {
PageResult<SysOperateLogDO> pageResult = operateLogService.getOperateLogPage(reqVO);
// 获得拼接需要的数据
Collection<Long> userIds = CollectionUtils.convertList(pageResult.getList(), SysOperateLogDO::getUserId);
@@ -82,11 +68,10 @@ public class SysOperateLogController {
@ApiOperation("导出操作日志")
@GetMapping("/export")
@PreAuthorize("@ss.hasPermission('system:operate-log:export')")
@OperateLog(type = EXPORT)
// @PreAuthorize("@ss.hasPermi('system:operate-log:export')")
public void exportOperateLog(HttpServletResponse response, @Validated SysOperateLogExportReqVO reqVO)
throws IOException {
List<SysOperateLogDO> list = operateLogService.listOperateLogs(reqVO);
public void exportOperateLog(HttpServletResponse response, @Valid SysOperateLogExportReqVO reqVO) throws IOException {
List<SysOperateLogDO> list = operateLogService.getOperateLogs(reqVO);
// 获得拼接需要的数据
Collection<Long> userIds = CollectionUtils.convertList(list, SysOperateLogDO::getUserId);
@@ -94,8 +79,7 @@ public class SysOperateLogController {
// 拼接数据
List<SysOperateLogExcelVO> excelDataList = SysOperateLogConvert.INSTANCE.convertList(list, userMap);
// 输出
ExcelUtils.write(response, "操作日志.xls", "数据列表",
SysOperateLogExcelVO.class, excelDataList);
ExcelUtils.write(response, "操作日志.xls", "数据列表", SysOperateLogExcelVO.class, excelDataList);
}
}

View File

@@ -11,62 +11,62 @@ import cn.iocoder.dashboard.modules.system.service.notice.SysNoticeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@Api(tags = "通知公告")
@RestController
@RequestMapping("/system/notice")
@Validated
public class SysNoticeController {
@Resource
private SysNoticeService noticeService;
@ApiOperation("获取通知公告列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:notice:list')")
public CommonResult<PageResult<SysNoticeRespVO>> pageNotices(@Validated SysNoticePageReqVO reqVO) {
return success(SysNoticeConvert.INSTANCE.convertPage(noticeService.pageNotices(reqVO)));
}
@ApiOperation("获得通知公告")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermi('system:notice:query')")
@GetMapping(value = "/get")
public CommonResult<SysNoticeRespVO> getNotice(@RequestParam("id") Long id) {
return success(SysNoticeConvert.INSTANCE.convert(noticeService.getNotice(id)));
}
@ApiOperation("新增通知公告")
// @PreAuthorize("@ss.hasPermi('system:notice:add')")
// @Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/create")
public CommonResult<Long> createNotice(@Validated @RequestBody SysNoticeCreateReqVO reqVO) {
@ApiOperation("创建通知公告")
@PreAuthorize("@ss.hasPermission('system:notice:create')")
public CommonResult<Long> createNotice(@Valid @RequestBody SysNoticeCreateReqVO reqVO) {
Long noticeId = noticeService.createNotice(reqVO);
return success(noticeId);
}
@PutMapping("/update")
@ApiOperation("修改通知公告")
// @PreAuthorize("@ss.hasPermi('system:notice:edit')")
// @Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/update")
public CommonResult<Boolean> updateNotice(@Validated @RequestBody SysNoticeUpdateReqVO reqVO) {
@PreAuthorize("@ss.hasPermission('system:notice:update')")
public CommonResult<Boolean> updateNotice(@Valid @RequestBody SysNoticeUpdateReqVO reqVO) {
noticeService.updateNotice(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除通知公告")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermi('system:notice:remove')")
// @Log(title = "通知公告", businessType = BusinessType.DELETE)
@PostMapping("/delete")
@PreAuthorize("@ss.hasPermission('system:notice:delete')")
public CommonResult<Boolean> deleteNotice(@RequestParam("id") Long id) {
noticeService.deleteNotice(id);
return success(true);
}
@GetMapping("/page")
@ApiOperation("获取通知公告列表")
@PreAuthorize("@ss.hasPermission('system:notice:quey')")
public CommonResult<PageResult<SysNoticeRespVO>> pageNotices(@Validated SysNoticePageReqVO reqVO) {
return success(SysNoticeConvert.INSTANCE.convertPage(noticeService.pageNotices(reqVO)));
}
@GetMapping("/get")
@ApiOperation("获得通知公告")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('system:notice:quey')")
public CommonResult<SysNoticeRespVO> getNotice(@RequestParam("id") Long id) {
return success(SysNoticeConvert.INSTANCE.convert(noticeService.getNotice(id)));
}
}

View File

@@ -9,10 +9,12 @@ import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Comparator;
import java.util.List;
@@ -21,78 +23,64 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@Api(tags = "菜单")
@RestController
@RequestMapping("/system/menu")
@Validated
public class SysMenuController {
@Resource
private SysMenuService menuService;
@ApiOperation("获取菜单列表")
// @PreAuthorize("@ss.hasPermi('system:menu:list')")
@GetMapping("/list")
public CommonResult<List<SysMenuRespVO>> listMenus(SysMenuListReqVO reqVO) {
List<SysMenuDO> list = menuService.listMenus(reqVO);
list.sort(Comparator.comparing(SysMenuDO::getSort));
return success(SysMenuConvert.INSTANCE.convertList(list));
}
@ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,主要用于前端的下拉选项")
@GetMapping("/list-all-simple")
public CommonResult<List<SysMenuSimpleRespVO>> listSimpleMenus() {
// 获得菜单列表,只要开启状态的
SysMenuListReqVO reqVO = new SysMenuListReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
List<SysMenuDO> list = menuService.listMenus(reqVO);
// 排序后,返回个诶前端
list.sort(Comparator.comparing(SysMenuDO::getSort));
return success(SysMenuConvert.INSTANCE.convertList02(list));
}
@ApiOperation("获取菜单信息")
@GetMapping("/get")
// @PreAuthorize("@ss.hasPermi('system:menu:query')")
public CommonResult<SysMenuRespVO> getMenu(Long id) {
SysMenuDO menu = menuService.getMenu(id);
return success(SysMenuConvert.INSTANCE.convert(menu));
}
// /**
// * 加载对应角色菜单列表树
// */
// @GetMapping(value = "/roleMenuTreeselect/{roleId}")
// public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
// List<SysMenu> menus = menuService.selectMenuList(loginUser.getUser().getUserId());
// AjaxResult ajax = AjaxResult.success();
// ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
// ajax.put("menus", menuService.buildMenuTreeSelect(menus));
// return ajax;
// }
@ApiOperation("创建菜单")
// @PreAuthorize("@ss.hasPermi('system:menu:add')")
// @Log(title = "菜单管理", businessType = BusinessType.INSERT)
@PostMapping("/create")
public CommonResult<Long> createMenu(@Validated @RequestBody SysMenuCreateReqVO reqVO) {
@ApiOperation("创建菜单")
@PreAuthorize("@ss.hasPermission('system:menu:create')")
public CommonResult<Long> createMenu(@Valid @RequestBody SysMenuCreateReqVO reqVO) {
Long menuId = menuService.createMenu(reqVO);
return success(menuId);
}
@PutMapping("/update")
@ApiOperation("修改菜单")
// @PreAuthorize("@ss.hasPermi('system:menu:edit')")
// @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PostMapping("/update")
public CommonResult<Boolean> updateMenu(@Validated @RequestBody SysMenuUpdateReqVO reqVO) {
@PreAuthorize("@ss.hasPermission('system:menu:update')")
public CommonResult<Boolean> updateMenu(@Valid @RequestBody SysMenuUpdateReqVO reqVO) {
menuService.updateMenu(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除菜单")
@PostMapping("/delete")
@ApiImplicitParam(name = "id", value = "角色编号", required= true, example = "1024", dataTypeClass = Long.class)
// @Log(title = "菜单管理", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermission('system:menu:delete')")
public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id) {
menuService.deleteMenu(id);
return success(true);
}
@GetMapping("/list")
@ApiOperation("获取菜单列表")
@PreAuthorize("@ss.hasPermission('system:menu:query')")
public CommonResult<List<SysMenuRespVO>> getMenus(SysMenuListReqVO reqVO) {
List<SysMenuDO> list = menuService.getMenus(reqVO);
list.sort(Comparator.comparing(SysMenuDO::getSort));
return success(SysMenuConvert.INSTANCE.convertList(list));
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,主要用于前端的下拉选项")
public CommonResult<List<SysMenuSimpleRespVO>> getSimpleMenus() {
// 获得菜单列表,只要开启状态的
SysMenuListReqVO reqVO = new SysMenuListReqVO();
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
List<SysMenuDO> list = menuService.getMenus(reqVO);
// 排序后,返回个诶前端
list.sort(Comparator.comparing(SysMenuDO::getSort));
return success(SysMenuConvert.INSTANCE.convertList02(list));
}
@GetMapping("/get")
@ApiOperation("获取菜单信息")
@PreAuthorize("@ss.hasPermission('system:menu:query')")
public CommonResult<SysMenuRespVO> getMenu(Long id) {
SysMenuDO menu = menuService.getMenu(id);
return success(SysMenuConvert.INSTANCE.convert(menu));
}
}

View File

@@ -4,6 +4,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.*;
import cn.iocoder.dashboard.modules.system.convert.permission.SysRoleConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
@@ -11,96 +12,95 @@ import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "角色")
@RestController
@RequestMapping("/system/role")
@Validated
public class SysRoleController {
@Resource
private SysRoleService roleService;
@ApiOperation("获得角色分页")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:role:list')")
public CommonResult<PageResult<SysRoleDO>> list(SysRolePageReqVO reqVO) {
return success(roleService.pageRole(reqVO));
}
@ApiOperation(value = "获取角色精简信息列表", notes = "只包含被开启的角色,主要用于前端的下拉选项")
@GetMapping("/list-all-simple")
public CommonResult<List<SysRoleSimpleRespVO>> listSimpleRoles() {
// 获得角色列表,只要开启状态的
List<SysRoleDO> list = roleService.listRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
// 排序后,返回个诶前端
list.sort(Comparator.comparing(SysRoleDO::getSort));
return success(SysRoleConvert.INSTANCE.convertList02(list));
}
@ApiOperation("创建角色")
@PostMapping("/create")
// @PreAuthorize("@ss.hasPermi('system:role:add')")
// @Log(title = "角色管理", businessType = BusinessType.INSERT)
public CommonResult<Long> add(@Validated @RequestBody SysRoleCreateReqVO reqVO) {
@ApiOperation("创建角色")
@PreAuthorize("@ss.hasPermission('system:role:create')")
public CommonResult<Long> createRole(@Valid @RequestBody SysRoleCreateReqVO reqVO) {
return success(roleService.createRole(reqVO));
}
@PutMapping("/update")
@ApiOperation("修改角色")
// @PreAuthorize("@ss.hasPermi('system:role:edit')")
// @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/update")
public CommonResult<Boolean> update(@Validated @RequestBody SysRoleUpdateReqVO reqVO) {
@PreAuthorize("@ss.hasPermission('system:role:update')")
public CommonResult<Boolean> updateRole(@Valid @RequestBody SysRoleUpdateReqVO reqVO) {
roleService.updateRole(reqVO);
return success(true);
}
@PutMapping("/update-status")
@ApiOperation("修改角色状态")
@PreAuthorize("@ss.hasPermission('system:role:update')")
public CommonResult<Boolean> updateRoleStatus(@Valid @RequestBody SysRoleUpdateStatusReqVO reqVO) {
roleService.updateRoleStatus(reqVO.getId(), reqVO.getStatus());
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除角色")
@PostMapping("/delete")
@ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermi('system:role:remove')")
// @Log(title = "角色管理", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermission('system:role:delete')")
public CommonResult<Boolean> deleteRole(@RequestParam("id") Long id) {
roleService.deleteRole(id);
return success(true);
}
@ApiOperation("获得角色信息")
@GetMapping("/get")
// @PreAuthorize("@ss.hasPermi('system:role:query')")
@ApiOperation("获得角色信息")
@PreAuthorize("@ss.hasPermission('system:role:query')")
public CommonResult<SysRoleRespVO> getRole(@RequestParam("id") Long id) {
SysRoleDO role = roleService.getRole(id);
return success(SysRoleConvert.INSTANCE.convert(role));
}
@ApiOperation("修改角色状态")
@PostMapping("/update-status")
// @PreAuthorize("@ss.hasPermi('system:role:edit')")
// @Log(title = "角色管理", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updateRoleStatus(@Validated @RequestBody SysRoleUpdateStatusReqVO reqVO) {
roleService.updateRoleStatus(reqVO.getId(), reqVO.getStatus());
return success(true);
@GetMapping("/page")
@ApiOperation("获得角色分页")
@PreAuthorize("@ss.hasPermission('system:role:query')")
public CommonResult<PageResult<SysRoleDO>> getRolePage(SysRolePageReqVO reqVO) {
return success(roleService.getRolePage(reqVO));
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获取角色精简信息列表", notes = "只包含被开启的角色,主要用于前端的下拉选项")
public CommonResult<List<SysRoleSimpleRespVO>> getSimpleRoles() {
// 获得角色列表,只要开启状态的
List<SysRoleDO> list = roleService.getRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
// 排序后,返回个诶前端
list.sort(Comparator.comparing(SysRoleDO::getSort));
return success(SysRoleConvert.INSTANCE.convertList02(list));
}
@GetMapping("/export")
// @Log(title = "角色管理", businessType = BusinessType.EXPORT)
// @PreAuthorize("@ss.hasPermi('system:role:export')")
@OperateLog(type = EXPORT)
@PreAuthorize("@ss.hasPermission('system:role:export')")
public void export(HttpServletResponse response, @Validated SysRoleExportReqVO reqVO) throws IOException {
List<SysRoleDO> list = roleService.listRoles(reqVO);
List<SysRoleExcelVO> excelDataList = SysRoleConvert.INSTANCE.convertList03(list);
List<SysRoleDO> list = roleService.getRoles(reqVO);
List<SysRoleExcelVO> data = SysRoleConvert.INSTANCE.convertList03(list);
// 输出
ExcelUtils.write(response, "角色数据.xls", "角色列表",
SysRoleExcelVO.class, excelDataList);
ExcelUtils.write(response, "角色数据.xls", "角色列表", SysRoleExcelVO.class, data);
}
}

View File

@@ -5,6 +5,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
@@ -25,14 +26,17 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "用户")
@RestController
@RequestMapping("/system/user")
@Validated
public class SysUserController {
@Resource
@@ -40,12 +44,53 @@ public class SysUserController {
@Resource
private SysDeptService deptService;
@PostMapping("/create")
@ApiOperation("新增用户")
@PreAuthorize("@ss.hasPermission('system:user:create')")
public CommonResult<Long> createUser(@Valid @RequestBody SysUserCreateReqVO reqVO) {
Long id = userService.createUser(reqVO);
return success(id);
}
@PutMapping("update")
@ApiOperation("修改用户")
@PreAuthorize("@ss.hasPermission('system:user:update')")
public CommonResult<Boolean> updateUser(@Valid @RequestBody SysUserUpdateReqVO reqVO) {
userService.updateUser(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除用户")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('system:user:delete')")
public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id) {
userService.deleteUser(id);
return success(true);
}
@PutMapping("/update-password")
@ApiOperation("重置用户密码")
@PreAuthorize("@ss.hasPermission('system:user:update-password')")
public CommonResult<Boolean> updateUserPassword(@Valid @RequestBody SysUserUpdatePasswordReqVO reqVO) {
userService.updateUserPassword(reqVO.getId(), reqVO.getPassword());
return success(true);
}
@PutMapping("/update-status")
@ApiOperation("修改用户状态")
@PreAuthorize("@ss.hasPermission('system:user:update')")
public CommonResult<Boolean> updateUserStatus(@Valid @RequestBody SysUserUpdateStatusReqVO reqVO) {
userService.updateUserStatus(reqVO.getId(), reqVO.getStatus());
return success(true);
}
@GetMapping("/page")
@ApiOperation("获得用户分页列表")
@PreAuthorize("@ss.hasPermission('system:user:list')")
public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) {
public CommonResult<PageResult<SysUserPageItemRespVO>> getUserPage(@Valid SysUserPageReqVO reqVO) {
// 获得用户分页列表
PageResult<SysUserDO> pageResult = userService.pageUsers(reqVO);
PageResult<SysUserDO> pageResult = userService.getUserPage(reqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return success(new PageResult<>(pageResult.getTotal())); // 返回空
}
@@ -63,71 +108,22 @@ public class SysUserController {
return success(new PageResult<>(userList, pageResult.getTotal()));
}
/**
* 根据用户编号获取详细信息
*/
@GetMapping("/get")
@ApiOperation("获得用户详情")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
// @PreAuthorize("@ss.hasPermi('system:user:query')")
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) {
return success(SysUserConvert.INSTANCE.convert(userService.getUser(id)));
}
@ApiOperation("新增用户")
@PostMapping("/create")
// @PreAuthorize("@ss.hasPermi('system:user:add')")
// @Log(title = "用户管理", businessType = BusinessType.INSERT)
public CommonResult<Long> createUser(@Validated @RequestBody SysUserCreateReqVO reqVO) {
Long id = userService.createUser(reqVO);
return success(id);
}
@ApiOperation("修改用户")
@PostMapping("update")
// @PreAuthorize("@ss.hasPermi('system:user:edit')")
// @Log(title = "用户管理", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updateUser(@Validated @RequestBody SysUserUpdateReqVO reqVO) {
userService.updateUser(reqVO);
return success(true);
}
@ApiOperation("删除用户")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PostMapping("/delete")
// @PreAuthorize("@ss.hasPermi('system:user:remove')")
// @Log(title = "用户管理", businessType = BusinessType.DELETE)
public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id) {
userService.deleteUser(id);
return success(true);
}
@ApiOperation("重置用户密码")
@PostMapping("/update-password")
// @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
// @Log(title = "用户管理", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updateUserPassword(@Validated @RequestBody SysUserUpdatePasswordReqVO reqVO) {
userService.updateUserPassword(reqVO.getId(), reqVO.getPassword());
return success(true);
}
@ApiOperation("修改用户状态")
@PostMapping("/update-status")
// @PreAuthorize("@ss.hasPermi('system:user:edit')")
// @Log(title = "用户管理", businessType = BusinessType.UPDATE)
public CommonResult<Boolean> updateUserStatus(@Validated @RequestBody SysUserUpdateStatusReqVO reqVO) {
userService.updateUserStatus(reqVO.getId(), reqVO.getStatus());
return success(true);
}
@ApiOperation("导出用户")
@GetMapping("/export")
// @PreAuthorize("@ss.hasPermi('system:user:export')") , @Validated SysUserExportReqVO reqVO
// @Log(title = "用户管理", businessType = BusinessType.EXPORT)
@ApiOperation("导出用户")
@PreAuthorize("@ss.hasPermission('system:user:export')")
@OperateLog(type = EXPORT)
public void exportUsers(@Validated SysUserExportReqVO reqVO,
HttpServletResponse response) throws IOException {
// 获得用户列表
List<SysUserDO> users = userService.listUsers(reqVO);
List<SysUserDO> users = userService.getUsers(reqVO);
// 获得拼接需要的数据
Collection<Long> deptIds = CollectionUtils.convertList(users, SysUserDO::getDeptId);
@@ -147,8 +143,8 @@ public class SysUserController {
ExcelUtils.write(response, "用户数据.xls", "用户列表", SysUserExcelVO.class, excelUsers);
}
@ApiOperation("获得导入用户模板")
@GetMapping("/get-import-template")
@ApiOperation("获得导入用户模板")
public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo
List<SysUserImportExcelVO> list = Arrays.asList(
@@ -159,21 +155,18 @@ public class SysUserController {
);
// 输出
ExcelUtils.write(response, "用户导入模板.xls", "用户列表",
SysUserImportExcelVO.class, list);
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", SysUserImportExcelVO.class, list);
}
@PostMapping("/import")
@ApiOperation("导入用户")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class),
@ApiImplicitParam(name = "updateSupport", value = "是否支持更新,默认为 false", example = "true", dataTypeClass = Boolean.class)
})
@PostMapping("/import")
// @Log(title = "用户管理", businessType = BusinessType.IMPORT)
// @PreAuthorize("@ss.hasPermi('system:user:import')")
@PreAuthorize("@ss.hasPermission('system:user:import')")
public CommonResult<SysUserImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
List<SysUserImportExcelVO> list = ExcelUtils.raed(file, SysUserImportExcelVO.class);
return success(userService.importUsers(list, updateSupport));
}

View File

@@ -1,49 +1,54 @@
package cn.iocoder.dashboard.modules.system.controller.user;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
import static cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.FILE_IS_EMPTY;
/**
* @author niudehua
*/
@Api(tags = "用户个人中心")
@RestController
@RequestMapping("/system/user/profile")
@Api(tags = "用户个人中心")
@Validated
@Slf4j
public class SysUserProfileController {
@Resource
private SysUserService userService;
@Resource
private SysDeptService deptService;
@Resource
private SysPostService postService;
@Resource
private SysPermissionService permissionService;
@Resource
private SysRoleService roleService;
@@ -51,30 +56,47 @@ public class SysUserProfileController {
@GetMapping("/get")
@ApiOperation("获得登录用户信息")
public CommonResult<SysUserProfileRespVO> profile() {
// 获用户信息
Long userId = SecurityFrameworkUtils.getLoginUserId();
SysUserDO user = userService.getUser(userId);
SysUserProfileRespVO userProfileRespVO = SysUserConvert.INSTANCE.convert03(user);
List<SysRoleDO> userRoles = roleService.listRolesFromCache(permissionService.listUserRoleIs(userId));
userProfileRespVO.setRoles(CollectionUtils.convertSet(userRoles, SysUserConvert.INSTANCE::convert));
return success(userProfileRespVO);
// 获用户基本信息
SysUserDO user = userService.getUser(getLoginUserId());
SysUserProfileRespVO resp = SysUserConvert.INSTANCE.convert03(user);
// 获得用户角色
List<SysRoleDO> userRoles = roleService.getRolesFromCache(permissionService.listUserRoleIs(user.getId()));
resp.setRoles(SysUserConvert.INSTANCE.convertList(userRoles));
// 获得部门信息
if (user.getDeptId() != null) {
SysDeptDO dept = deptService.getDept(user.getDeptId());
resp.setDept(SysUserConvert.INSTANCE.convert02(dept));
}
// 获得岗位信息
if (CollUtil.isNotEmpty(user.getPostIds())) {
List<SysPostDO> posts = postService.getPosts(user.getPostIds());
resp.setPosts(SysUserConvert.INSTANCE.convertList02(posts));
}
return success(resp);
}
@PostMapping("/update")
@PutMapping("/update")
@ApiOperation("修改用户个人信息")
public CommonResult<Boolean> updateProfile(@RequestBody SysUserProfileUpdateReqVO reqVO, HttpServletRequest request) {
userService.updateUserProfile(reqVO);
SecurityFrameworkUtils.setLoginUser(SysAuthConvert.INSTANCE.convert(reqVO), request);
public CommonResult<Boolean> updateUserProfile(@Valid @RequestBody SysUserProfileUpdateReqVO reqVO) {
userService.updateUserProfile(getLoginUserId(), reqVO);
return success(true);
}
@PostMapping("/upload-avatar")
@PutMapping("/update-password")
@ApiOperation("修改用户个人密码")
public CommonResult<Boolean> updateUserProfilePassword(@Valid @RequestBody SysUserProfileUpdatePasswordReqVO reqVO) {
userService.updateUserPassword(getLoginUserId(), reqVO);
return success(true);
}
@PutMapping("/upload-avatar")
@ApiOperation("上传用户个人头像")
public CommonResult<Boolean> uploadAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
public CommonResult<Boolean> updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
if (file.isEmpty()) {
throw ServiceExceptionUtil.exception(FILE_IS_EMPTY);
}
userService.updateAvatar(SecurityFrameworkUtils.getLoginUserId(), file.getInputStream());
userService.updateUserAvatar(getLoginUserId(), file.getInputStream());
return success(true);
}
}

View File

@@ -0,0 +1,88 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserBaseVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用户个人中心信息 Response VO")
public class SysUserProfileRespVO extends SysUserBaseVO {
@ApiModelProperty(value = "用户编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 SysCommonStatusEnum 枚举类")
private Integer status;
@ApiModelProperty(value = "最后登陆 IP", required = true, example = "192.168.1.1")
private String loginIp;
@ApiModelProperty(value = "最后登录时间", required = true, example = "时间戳格式")
private Date loginDate;
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
private Date createTime;
/**
* 所属角色
*/
private List<Role> roles;
/**
* 所在部门
*/
private Dept dept;
/**
* 所属岗位数组
*/
private List<Post> posts;
@ApiModel("角色")
@Data
public static class Role {
@ApiModelProperty(value = "角色编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "角色名称", required = true, example = "普通角色")
private String name;
}
@ApiModel("部门")
@Data
public static class Dept {
@ApiModelProperty(value = "部门编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "部门名称", required = true, example = "研发部")
private String name;
}
@ApiModel("岗位")
@Data
public static class Post {
@ApiModelProperty(value = "岗位编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "岗位名称", required = true, example = "开发")
private String name;
}
}

View File

@@ -0,0 +1,24 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
@ApiModel("用户个人中心更新密码 Request VO")
@Data
public class SysUserProfileUpdatePasswordReqVO {
@ApiModelProperty(value = "旧密码", required = true, example = "123456")
@NotEmpty(message = "旧密码不能为空")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String oldPassword;
@ApiModelProperty(value = "新密码", required = true, example = "654321")
@NotEmpty(message = "新密码不能为空")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String newPassword;
}

View File

@@ -1,44 +1,31 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@ApiModel("用户个人信息更新 Request VO")
@Data
public class SysUserProfileUpdateReqVO {
@ApiModelProperty(value = "用户编号", required = true, example = "1024")
@NotNull(message = "用户编号不能为空")
private Long id;
@ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
@Size(max = 30, message = "用户昵称长度不能超过30个字符")
private String nickname;
@ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn")
@Email(message = "邮箱格式不正确")
@Size(max = 50, message = "邮箱长度不能超过50个字符")
@Size(max = 50, message = "邮箱长度不能超过 50 个字符")
private String email;
@ApiModelProperty(value = "手机号码", example = "15601691300")
@Size(max = 11, message = "手机号码长度不能超过11个字符")
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
private String mobile;
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
private Integer sex;
@ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png")
private String avatar;
@ApiModelProperty(value = "旧密码", required = true, example = "123456")
private String oldPassword;
@ApiModelProperty(value = "新密码", required = true, example = "654321")
private String newPassword;
}

View File

@@ -5,6 +5,7 @@ import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.Set;
@@ -35,11 +36,11 @@ public class SysUserBaseVO {
@ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn")
@Email(message = "邮箱格式不正确")
@Size(max = 50, message = "邮箱长度不能超过50个字符")
@Size(max = 50, message = "邮箱长度不能超过 50 个字符")
private String email;
@ApiModelProperty(value = "手机号码", example = "15601691300")
@Size(max = 11, message = "手机号码长度不能超过11个字符")
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
private String mobile;
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
@@ -48,5 +49,4 @@ public class SysUserBaseVO {
@ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png")
private String avatar;
}

View File

@@ -1,6 +1,5 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
@@ -18,7 +17,6 @@ public class SysUserPageItemRespVO extends SysUserRespVO {
/**
* 所在部门
*/
@JsonIgnore
private Dept dept;
@ApiModel("部门")

View File

@@ -1,37 +0,0 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.util.Set;
@ApiModel("用户个人中心信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SysUserProfileRespVO extends SysUserRespVO {
/**
* 所属角色
*/
@ApiModelProperty(value = "所属角色", required = true, example = "123456")
private Set<Role> roles;
@ApiModel("角色")
@Data
public static class Role {
@ApiModelProperty(value = "角色编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "角色名称", required = true, example = "普通角色")
private String name;
}
}

View File

@@ -3,7 +3,8 @@ package cn.iocoder.dashboard.modules.system.convert.auth;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
@@ -41,6 +42,8 @@ public interface SysAuthConvert {
LoginUser convert(SysUserProfileUpdateReqVO reqVO);
LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO);
/**
* 将菜单列表,构建成菜单树
*

View File

@@ -1,18 +1,18 @@
package cn.iocoder.dashboard.modules.system.convert.user;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExcelVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface SysUserConvert {
@@ -32,10 +32,14 @@ public interface SysUserConvert {
SysUserProfileRespVO convert03(SysUserDO bean);
SysUserProfileRespVO.Role convert(SysRoleDO bean);
List<SysUserProfileRespVO.Role> convertList(List<SysRoleDO> list);
SysUserProfileRespVO.Dept convert02(SysDeptDO bean);
SysUserDO convert(SysUserProfileUpdateReqVO bean);
SysUserDO convert(SysUserProfileUpdatePasswordReqVO bean);
List<SysUserProfileRespVO.Post> convertList02(List<SysPostDO> list);
}

View File

@@ -4,6 +4,7 @@ import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleMenuDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.Collection;
import java.util.Date;
@@ -32,10 +33,16 @@ public interface SysRoleMenuMapper extends BaseMapperX<SysRoleMenuDO> {
delete(new QueryWrapper<SysRoleMenuDO>().eq("role_id", roleId)
.in("menu_id", menuIds));
}
default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {
return selectOne(new QueryWrapper<SysRoleMenuDO>().select("id")
.gt("update_time", maxUpdateTime).last("LIMIT 1")) != null;
default void deleteListByMenuId(Long menuId) {
delete(new QueryWrapper<SysRoleMenuDO>().eq("menu_id", menuId));
}
default void deleteListByRoleId(Long roleId) {
delete(new QueryWrapper<SysRoleMenuDO>().eq("role_id", roleId));
}
@Select("SELECT id FROM sys_role_menu WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
}

View File

@@ -1,8 +1,8 @@
package cn.iocoder.dashboard.modules.system.dal.mysql.permission;
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysUserRoleDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
@@ -10,7 +10,7 @@ import java.util.List;
import java.util.stream.Collectors;
@Mapper
public interface SysUserRoleMapper extends BaseMapper<SysUserRoleDO> {
public interface SysUserRoleMapper extends BaseMapperX<SysUserRoleDO> {
default List<SysUserRoleDO> selectListByUserId(Long userId) {
return selectList(new QueryWrapper<SysUserRoleDO>().eq("user_id", userId));
@@ -32,4 +32,12 @@ public interface SysUserRoleMapper extends BaseMapper<SysUserRoleDO> {
.in("role_id", roleIds));
}
default void deleteListByUserId(Long userId) {
delete(new QueryWrapper<SysUserRoleDO>().eq("user_id", userId));
}
default void deleteListByRoleId(Long roleId) {
delete(new QueryWrapper<SysUserRoleDO>().eq("role_id", roleId));
}
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.dashboard.modules.system.mq.consumer.mail;
import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
import cn.iocoder.dashboard.modules.system.mq.message.mail.SysMailSendMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class SysMailSendConsumer extends AbstractStreamMessageListener<SysMailSendMessage> {
@Override
public void onMessage(SysMailSendMessage message) {
log.info("[onMessage][消息内容({})]", message);
}
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.dashboard.modules.system.mq.consumer.sms;
import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class SysSmsSendConsumer extends AbstractStreamMessageListener<SysSmsSendMessage> {
@Override
public void onMessage(SysSmsSendMessage message) {
log.info("[onMessage][消息内容({})]", message);
}
}

View File

@@ -0,0 +1,46 @@
package cn.iocoder.dashboard.modules.system.mq.message.mail;
import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Map;
/**
* 邮箱发送消息
*
* @author 芋道源码
*/
@Data
public class SysMailSendMessage implements StreamMessage {
/**
* 邮箱地址
*/
@NotNull(message = "邮箱地址不能为空")
private String address;
/**
* 短信模板编号
*/
@NotNull(message = "短信模板编号不能为空")
private String templateCode;
/**
* 短信模板参数
*/
private Map<String, Object> templateParams;
/**
* 用户编号,允许空
*/
private Integer userId;
/**
* 用户类型,允许空
*/
private Integer userType;
@Override
public String getStreamKey() {
return "system.mail.send";
}
}

View File

@@ -0,0 +1,46 @@
package cn.iocoder.dashboard.modules.system.mq.message.sms;
import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Map;
/**
* 短信发送消息
*
* @author 芋道源码
*/
@Data
public class SysSmsSendMessage implements StreamMessage {
/**
* 手机号
*/
@NotNull(message = "手机号不能为空")
private String mobile;
/**
* 短信模板编号
*/
@NotNull(message = "短信模板编号不能为空")
private String templateCode;
/**
* 短信模板参数
*/
private Map<String, Object> templateParams;
/**
* 用户编号,允许空
*/
private Integer userId;
/**
* 用户类型,允许空
*/
private Integer userType;
@Override
public String getStreamKey() {
return "system.sms.send";
}
}

View File

@@ -61,7 +61,7 @@ public class SysAuthServiceImpl implements SysAuthService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 获取 username 对应的 SysUserDO
SysUserDO user = userService.getUserByUserName(username);
SysUserDO user = userService.getUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}

View File

@@ -101,7 +101,7 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
// 处理基于用户昵称的查询
Collection<Long> userIds = null;
if (StrUtil.isNotEmpty(reqVO.getUsername())) {
userIds = convertSet(userService.listUsersByUsername(reqVO.getUsername()), SysUserDO::getId);
userIds = convertSet(userService.getUsersByUsername(reqVO.getUsername()), SysUserDO::getId);
if (CollUtil.isEmpty(userIds)) {
return PageResult.empty();
}

View File

@@ -24,53 +24,6 @@ public interface SysDeptService {
*/
void initLocalCache();
/**
* 获得指定编号的部门列表
*
* @param ids 部门编号数组
* @return 部门列表
*/
List<SysDeptDO> listDepts(Collection<Long> ids);
/**
* 获得指定编号的部门 Map
*
* @param ids 部门编号数组
* @return 部门 Map
*/
default Map<Long, SysDeptDO> getDeptMap(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyMap();
}
List<SysDeptDO> list = listDepts(ids);
return CollectionUtils.convertMap(list, SysDeptDO::getId);
}
/**
* 筛选部门列表
*
* @param reqVO 筛选条件请求 VO
* @return 部门列表
*/
List<SysDeptDO> listDepts(SysDeptListReqVO reqVO);
/**
* 获得所有子部门,从缓存中
*
* @param parentId 部门编号
* @param recursive 是否递归获取所有
* @return 子部门列表
*/
List<SysDeptDO> listDeptsByParentIdFromCache(Long parentId, boolean recursive);
/**
* 获得部门信息
*
* @param id 部门编号
* @return 部门信息
*/
SysDeptDO getDept(Long id);
/**
* 创建部门
*
@@ -93,4 +46,51 @@ public interface SysDeptService {
*/
void deleteDept(Long id);
/**
* 获得指定编号的部门列表
*
* @param ids 部门编号数组
* @return 部门列表
*/
List<SysDeptDO> getSimpleDepts(Collection<Long> ids);
/**
* 获得指定编号的部门 Map
*
* @param ids 部门编号数组
* @return 部门 Map
*/
default Map<Long, SysDeptDO> getDeptMap(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyMap();
}
List<SysDeptDO> list = getSimpleDepts(ids);
return CollectionUtils.convertMap(list, SysDeptDO::getId);
}
/**
* 筛选部门列表
*
* @param reqVO 筛选条件请求 VO
* @return 部门列表
*/
List<SysDeptDO> getSimpleDepts(SysDeptListReqVO reqVO);
/**
* 获得部门信息
*
* @param id 部门编号
* @return 部门信息
*/
SysDeptDO getDept(Long id);
/**
* 获得所有子部门,从缓存中
*
* @param parentId 部门编号
* @param recursive 是否递归获取所有
* @return 子部门列表
*/
List<SysDeptDO> getDeptsByParentIdFromCache(Long parentId, boolean recursive);
}

View File

@@ -1,5 +1,6 @@
package cn.iocoder.dashboard.modules.system.service.dept;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExportReqVO;
@@ -11,6 +12,8 @@ import org.springframework.lang.Nullable;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.dashboard.util.collection.SetUtils.asSet;
/**
* 岗位 Service 接口
*
@@ -18,39 +21,6 @@ import java.util.List;
*/
public interface SysPostService {
/**
* 获得符合条件的岗位列表
*
* @param ids 岗位编号数组。如果为空,不进行筛选
* @param statuses 状态数组。如果为空,不进行筛选
* @return 部门列表
*/
List<SysPostDO> listPosts(@Nullable Collection<Long> ids, @Nullable Collection<Integer> statuses);
/**
* 获得岗位分页列表
*
* @param reqVO 分页条件
* @return 部门分页列表
*/
PageResult<SysPostDO> pagePosts(SysPostPageReqVO reqVO);
/**
* 获得岗位列表
*
* @param reqVO 查询条件
* @return 部门列表
*/
List<SysPostDO> listPosts(SysPostExportReqVO reqVO);
/**
* 获得岗位信息
*
* @param id 岗位编号
* @return 岗位信息
*/
SysPostDO getPost(Long id);
/**
* 创建岗位
*
@@ -73,4 +43,47 @@ public interface SysPostService {
*/
void deletePost(Long id);
/**
* 获得岗位列表
*
* @param ids 岗位编号数组。如果为空,不进行筛选
* @return 部门列表
*/
default List<SysPostDO> getPosts(@Nullable Collection<Long> ids) {
return getPosts(ids, asSet(CommonStatusEnum.ENABLE.getStatus(), CommonStatusEnum.DISABLE.getStatus()));
}
/**
* 获得符合条件的岗位列表
*
* @param ids 岗位编号数组。如果为空,不进行筛选
* @param statuses 状态数组。如果为空,不进行筛选
* @return 部门列表
*/
List<SysPostDO> getPosts(@Nullable Collection<Long> ids, @Nullable Collection<Integer> statuses);
/**
* 获得岗位分页列表
*
* @param reqVO 分页条件
* @return 部门分页列表
*/
PageResult<SysPostDO> getPostPage(SysPostPageReqVO reqVO);
/**
* 获得岗位列表
*
* @param reqVO 查询条件
* @return 部门列表
*/
List<SysPostDO> getPosts(SysPostExportReqVO reqVO);
/**
* 获得岗位信息
*
* @param id 岗位编号
* @return 岗位信息
*/
SysPostDO getPost(Long id);
}

View File

@@ -19,6 +19,7 @@ import com.google.common.collect.Multimap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@@ -32,6 +33,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
* @author 芋道源码
*/
@Service
@Validated
@Slf4j
public class SysDeptServiceImpl implements SysDeptService {
@@ -47,6 +49,7 @@ public class SysDeptServiceImpl implements SysDeptService {
*
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
*/
@SuppressWarnings("FieldCanBeLocal")
private volatile Map<Long, SysDeptDO> deptCache;
/**
* 父部门缓存
@@ -118,17 +121,54 @@ public class SysDeptServiceImpl implements SysDeptService {
}
@Override
public List<SysDeptDO> listDepts(Collection<Long> ids) {
public Long createDept(SysDeptCreateReqVO reqVO) {
// 校验正确性
checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName());
// 插入部门
SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO);
deptMapper.insert(dept);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
return dept.getId();
}
@Override
public void updateDept(SysDeptUpdateReqVO reqVO) {
// 校验正确性
checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
// 更新部门
SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO);
deptMapper.updateById(updateObj);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
}
@Override
public void deleteDept(Long id) {
// 校验是否存在
checkDeptExists(id);
// 校验是否有子部门
if (deptMapper.selectCountByParentId(id) > 0) {
throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN);
}
// 删除部门
deptMapper.deleteById(id);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
}
@Override
public List<SysDeptDO> getSimpleDepts(Collection<Long> ids) {
return deptMapper.selectBatchIds(ids);
}
@Override
public List<SysDeptDO> listDepts(SysDeptListReqVO reqVO) {
public List<SysDeptDO> getSimpleDepts(SysDeptListReqVO reqVO) {
return deptMapper.selectList(reqVO);
}
@Override
public List<SysDeptDO> listDeptsByParentIdFromCache(Long parentId, boolean recursive) {
public List<SysDeptDO> getDeptsByParentIdFromCache(Long parentId, boolean recursive) {
List<SysDeptDO> result = new ArrayList<>();
// 递归,简单粗暴
this.listDeptsByParentIdFromCache(result, parentId,
@@ -167,44 +207,6 @@ public class SysDeptServiceImpl implements SysDeptService {
return deptMapper.selectById(id);
}
@Override
public Long createDept(SysDeptCreateReqVO reqVO) {
// 校验正确性
checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName());
// 插入部门
SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO);
deptMapper.insert(dept);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
return dept.getId();
}
@Override
public void updateDept(SysDeptUpdateReqVO reqVO) {
// 校验正确性
checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
// 更新部门
SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO);
deptMapper.updateById(updateObj);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
}
@Override
public void deleteDept(Long id) {
// 校验是否存在
checkDeptExists(id);
// 校验是否有子部门
if (deptMapper.selectCountByParentId(id) > 0) {
throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN);
}
// 删除部门
deptMapper.deleteById(id);
// TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
}
private void checkCreateOrUpdate(Long id, Long parentId, String name) {
// 校验自己存在
checkDeptExists(id);
@@ -232,7 +234,7 @@ public class SysDeptServiceImpl implements SysDeptService {
throw ServiceExceptionUtil.exception(DEPT_NOT_ENABLE);
}
// 父部门不能是原来的子部门
List<SysDeptDO> children = this.listDeptsByParentIdFromCache(id, true);
List<SysDeptDO> children = this.getDeptsByParentIdFromCache(id, true);
if (children.stream().anyMatch(dept1 -> dept1.getId().equals(parentId))) {
throw ServiceExceptionUtil.exception(DEPT_PARENT_IS_CHILD);
}
@@ -262,12 +264,6 @@ public class SysDeptServiceImpl implements SysDeptService {
}
}
// /**
// * 查询部门管理数据
// *
// * @param dept 部门信息
// * @return 部门信息集合
// */
// @Override
// @DataScope(deptAlias = "d")
// public List<SysDept> selectDeptList(SysDept dept)

View File

@@ -11,6 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dept.SysPostMapper;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
@@ -24,31 +25,12 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
* @author 芋道源码
*/
@Service
@Validated
public class SysPostServiceImpl implements SysPostService {
@Resource
private SysPostMapper postMapper;
@Override
public List<SysPostDO> listPosts(Collection<Long> ids, Collection<Integer> statuses) {
return postMapper.selectList(ids, statuses);
}
@Override
public PageResult<SysPostDO> pagePosts(SysPostPageReqVO reqVO) {
return postMapper.selectPage(reqVO);
}
@Override
public List<SysPostDO> listPosts(SysPostExportReqVO reqVO) {
return postMapper.selectList(reqVO);
}
@Override
public SysPostDO getPost(Long id) {
return postMapper.selectById(id);
}
@Override
public Long createPost(SysPostCreateReqVO reqVO) {
// 校验正确性
@@ -68,6 +50,34 @@ public class SysPostServiceImpl implements SysPostService {
postMapper.updateById(updateObj);
}
@Override
public void deletePost(Long id) {
// 校验是否存在
this.checkPostExists(id);
// 删除部门
postMapper.deleteById(id);
}
@Override
public List<SysPostDO> getPosts(Collection<Long> ids, Collection<Integer> statuses) {
return postMapper.selectList(ids, statuses);
}
@Override
public PageResult<SysPostDO> getPostPage(SysPostPageReqVO reqVO) {
return postMapper.selectPage(reqVO);
}
@Override
public List<SysPostDO> getPosts(SysPostExportReqVO reqVO) {
return postMapper.selectList(reqVO);
}
@Override
public SysPostDO getPost(Long id) {
return postMapper.selectById(id);
}
private void checkCreateOrUpdate(Long id, String name, String code) {
// 校验自己存在
checkPostExists(id);
@@ -105,14 +115,6 @@ public class SysPostServiceImpl implements SysPostService {
}
}
@Override
public void deletePost(Long id) {
// 校验是否存在
this.checkPostExists(id);
// 删除部门
postMapper.deleteById(id);
}
private void checkPostExists(Long id) {
if (id == null) {
return;

View File

@@ -22,37 +22,6 @@ public interface SysDictDataService extends DictDataFrameworkService {
*/
void initLocalCache();
/**
* 获得字典数据列表
*
* @return 字典数据全列表
*/
List<SysDictDataDO> getDictDataList();
/**
* 获得字典数据分页列表
*
* @param reqVO 分页请求
* @return 字典数据分页列表
*/
PageResult<SysDictDataDO> getDictDataPage(SysDictDataPageReqVO reqVO);
/**
* 获得字典数据列表
*
* @param reqVO 列表请求
* @return 字典数据列表
*/
List<SysDictDataDO> getDictDataList(SysDictDataExportReqVO reqVO);
/**
* 获得字典数据详情
*
* @param id 字典数据编号
* @return 字典数据
*/
SysDictDataDO getDictData(Long id);
/**
* 创建字典数据
*
@@ -75,6 +44,37 @@ public interface SysDictDataService extends DictDataFrameworkService {
*/
void deleteDictData(Long id);
/**
* 获得字典数据列表
*
* @return 字典数据全列表
*/
List<SysDictDataDO> getDictDatas();
/**
* 获得字典数据分页列表
*
* @param reqVO 分页请求
* @return 字典数据分页列表
*/
PageResult<SysDictDataDO> getDictDataPage(SysDictDataPageReqVO reqVO);
/**
* 获得字典数据列表
*
* @param reqVO 列表请求
* @return 字典数据列表
*/
List<SysDictDataDO> getDictDatas(SysDictDataExportReqVO reqVO);
/**
* 获得字典数据详情
*
* @param id 字典数据编号
* @return 字典数据
*/
SysDictDataDO getDictData(Long id);
/**
* 获得指定字典类型的数据数量
*

View File

@@ -16,6 +16,28 @@ import java.util.List;
*/
public interface SysDictTypeService {
/**
* 创建字典类型
*
* @param reqVO 字典类型信息
* @return 字典类型编号
*/
Long createDictType(SysDictTypeCreateReqVO reqVO);
/**
* 更新字典类型
*
* @param reqVO 字典类型信息
*/
void updateDictType(SysDictTypeUpdateReqVO reqVO);
/**
* 删除字典类型
*
* @param id 字典类型编号
*/
void deleteDictType(Long id);
/**
* 获得字典类型分页列表
*
@@ -48,28 +70,6 @@ public interface SysDictTypeService {
*/
SysDictTypeDO getDictType(String type);
/**
* 创建字典类型
*
* @param reqVO 字典类型信息
* @return 字典类型编号
*/
Long createDictType(SysDictTypeCreateReqVO reqVO);
/**
* 更新字典类型
*
* @param reqVO 字典类型信息
*/
void updateDictType(SysDictTypeUpdateReqVO reqVO);
/**
* 删除字典类型
*
* @param id 字典类型编号
*/
void deleteDictType(Long id);
/**
* 获得全部字典类型列表
*

View File

@@ -131,7 +131,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
}
@Override
public List<SysDictDataDO> getDictDataList() {
public List<SysDictDataDO> getDictDatas() {
List<SysDictDataDO> list = dictDataMapper.selectList();
list.sort(COMPARATOR_TYPE_AND_SORT);
return list;
@@ -143,7 +143,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
}
@Override
public List<SysDictDataDO> getDictDataList(SysDictDataExportReqVO reqVO) {
public List<SysDictDataDO> getDictDatas(SysDictDataExportReqVO reqVO) {
List<SysDictDataDO> list = dictDataMapper.selectList(reqVO);
list.sort(COMPARATOR_TYPE_AND_SORT);
return list;

View File

@@ -19,7 +19,7 @@ public interface SysOperateLogService extends OperateLogFrameworkService {
* @param reqVO 分页条件
* @return 操作日志分页列表
*/
PageResult<SysOperateLogDO> pageOperateLog(SysOperateLogPageReqVO reqVO);
PageResult<SysOperateLogDO> getOperateLogPage(SysOperateLogPageReqVO reqVO);
/**
* 获得操作日志列表
@@ -27,6 +27,6 @@ public interface SysOperateLogService extends OperateLogFrameworkService {
* @param reqVO 列表条件
* @return 日志列表
*/
List<SysOperateLogDO> listOperateLogs(SysOperateLogExportReqVO reqVO);
List<SysOperateLogDO> getOperateLogs(SysOperateLogExportReqVO reqVO);
}

View File

@@ -55,11 +55,11 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
}
@Override
public PageResult<SysOperateLogDO> pageOperateLog(SysOperateLogPageReqVO reqVO) {
public PageResult<SysOperateLogDO> getOperateLogPage(SysOperateLogPageReqVO reqVO) {
// 处理基于用户昵称的查询
Collection<Long> userIds = null;
if (StrUtil.isNotEmpty(reqVO.getUserNickname())) {
userIds = convertSet(userService.listUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
userIds = convertSet(userService.getUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
if (CollUtil.isEmpty(userIds)) {
return PageResult.empty();
}
@@ -69,11 +69,11 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
}
@Override
public List<SysOperateLogDO> listOperateLogs(SysOperateLogExportReqVO reqVO) {
public List<SysOperateLogDO> getOperateLogs(SysOperateLogExportReqVO reqVO) {
// 处理基于用户昵称的查询
Collection<Long> userIds = null;
if (StrUtil.isNotEmpty(reqVO.getUserNickname())) {
userIds = convertSet(userService.listUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
userIds = convertSet(userService.getUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
if (CollUtil.isEmpty(userIds)) {
return Collections.emptyList();
}

View File

@@ -11,22 +11,6 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.notice.SysNoticeDO;
*/
public interface SysNoticeService {
/**
* 获得岗位公告公告分页列表
*
* @param reqVO 分页条件
* @return 部门分页列表
*/
PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO);
/**
* 获得岗位公告公告信息
*
* @param id 岗位公告公告编号
* @return 岗位公告公告信息
*/
SysNoticeDO getNotice(Long id);
/**
* 创建岗位公告公告
*
@@ -48,4 +32,21 @@ public interface SysNoticeService {
* @param id 岗位公告公告编号
*/
void deleteNotice(Long id);
/**
* 获得岗位公告公告分页列表
*
* @param reqVO 分页条件
* @return 部门分页列表
*/
PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO);
/**
* 获得岗位公告公告信息
*
* @param id 岗位公告公告编号
* @return 岗位公告公告信息
*/
SysNoticeDO getNotice(Long id);
}

View File

@@ -27,16 +27,6 @@ public class SysNoticeServiceImpl implements SysNoticeService {
@Resource
private SysNoticeMapper noticeMapper;
@Override
public PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO) {
return noticeMapper.selectPage(reqVO);
}
@Override
public SysNoticeDO getNotice(Long id) {
return noticeMapper.selectById(id);
}
@Override
public Long createNotice(SysNoticeCreateReqVO reqVO) {
SysNoticeDO notice = SysNoticeConvert.INSTANCE.convert(reqVO);
@@ -61,6 +51,16 @@ public class SysNoticeServiceImpl implements SysNoticeService {
noticeMapper.deleteById(id);
}
@Override
public PageResult<SysNoticeDO> pageNotices(SysNoticePageReqVO reqVO) {
return noticeMapper.selectPage(reqVO);
}
@Override
public SysNoticeDO getNotice(Long id) {
return noticeMapper.selectById(id);
}
@VisibleForTesting
public void checkNoticeExists(Long id) {
if (id == null) {

View File

@@ -20,12 +20,34 @@ public interface SysMenuService {
*/
void initLocalCache();
/**
* 创建菜单
*
* @param reqVO 菜单信息
* @return 创建出来的菜单编号
*/
Long createMenu(SysMenuCreateReqVO reqVO);
/**
* 更新菜单
*
* @param reqVO 菜单信息
*/
void updateMenu(SysMenuUpdateReqVO reqVO);
/**
* 删除菜单
*
* @param id 菜单编号
*/
void deleteMenu(Long id);
/**
* 获得所有菜单列表
*
* @return 菜单列表
*/
List<SysMenuDO> listMenus();
List<SysMenuDO> getMenus();
/**
* 筛选菜单列表
@@ -33,7 +55,7 @@ public interface SysMenuService {
* @param reqVO 筛选条件请求 VO
* @return 菜单列表
*/
List<SysMenuDO> listMenus(SysMenuListReqVO reqVO);
List<SysMenuDO> getMenus(SysMenuListReqVO reqVO);
/**
* 获得所有菜单,从缓存中
@@ -67,28 +89,6 @@ public interface SysMenuService {
*/
List<SysMenuDO> getMenuListByPermissionFromCache(String permission);
/*
* 创建菜单
*
* @param reqVO 菜单信息
* @return 创建出来的菜单编号
*/
Long createMenu(SysMenuCreateReqVO reqVO);
/**
* 更新菜单
*
* @param reqVO 菜单信息
*/
void updateMenu(SysMenuUpdateReqVO reqVO);
/**
* 删除菜单
*
* @param id 菜单编号
*/
void deleteMenu(Long id);
/**
* 获得菜单
*

View File

@@ -32,8 +32,8 @@ public interface SysPermissionService extends SecurityPermissionFrameworkService
* @param menusStatuses 菜单状态数组
* @return 菜单列表
*/
List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
Collection<Integer> menusStatuses);
List<SysMenuDO> getRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
Collection<Integer> menusStatuses);
/**
* 获得用户拥有的角色编号集合

View File

@@ -24,48 +24,6 @@ public interface SysRoleService {
*/
void initLocalCache();
/**
* 获得角色,从缓存中
*
* @param id 角色编号
* @return 角色
*/
SysRoleDO getRoleFromCache(Long id);
/**
* 获得角色列表
*
* @param statuses 筛选的状态。允许空,空时不筛选
* @return 角色列表
*/
List<SysRoleDO> listRoles(@Nullable Collection<Integer> statuses);
/**
* 获得角色数组,从缓存中
*
* @param ids 角色编号数组
* @return 角色数组
*/
List<SysRoleDO> listRolesFromCache(Collection<Long> ids);
/**
* 判断角色数组中,是否有管理员
*
* @param roleList 角色数组
* @return 是否有管理员
*/
boolean hasAnyAdmin(Collection<SysRoleDO> roleList);
/**
* 判断角色编号数组中,是否有管理员
*
* @param ids 角色编号数组
* @return 是否有管理员
*/
default boolean hasAnyAdmin(Set<Long> ids) {
return hasAnyAdmin(listRolesFromCache(ids));
}
/**
* 创建角色
*
@@ -88,30 +46,6 @@ public interface SysRoleService {
*/
void deleteRole(Long id);
/**
* 获得角色
*
* @param id 角色编号
* @return 角色
*/
SysRoleDO getRole(Long id);
/**
* 获得角色分页
*
* @param reqVO 角色分页查询
* @return 角色分页结果
*/
PageResult<SysRoleDO> pageRole(SysRolePageReqVO reqVO);
/**
* 获得角色列表
*
* @param reqVO 列表查询
* @return 角色列表
*/
List<SysRoleDO> listRoles(SysRoleExportReqVO reqVO);
/**
* 更新角色状态
*
@@ -129,4 +63,70 @@ public interface SysRoleService {
*/
void updateRoleDataScope(Long id, Integer dataScope, Set<Long> dataScopeDeptIds);
/**
* 获得角色,从缓存中
*
* @param id 角色编号
* @return 角色
*/
SysRoleDO getRoleFromCache(Long id);
/**
* 获得角色列表
*
* @param statuses 筛选的状态。允许空,空时不筛选
* @return 角色列表
*/
List<SysRoleDO> getRoles(@Nullable Collection<Integer> statuses);
/**
* 获得角色数组,从缓存中
*
* @param ids 角色编号数组
* @return 角色数组
*/
List<SysRoleDO> getRolesFromCache(Collection<Long> ids);
/**
* 判断角色数组中,是否有管理员
*
* @param roleList 角色数组
* @return 是否有管理员
*/
boolean hasAnyAdmin(Collection<SysRoleDO> roleList);
/**
* 判断角色编号数组中,是否有管理员
*
* @param ids 角色编号数组
* @return 是否有管理员
*/
default boolean hasAnyAdmin(Set<Long> ids) {
return hasAnyAdmin(getRolesFromCache(ids));
}
/**
* 获得角色
*
* @param id 角色编号
* @return 角色
*/
SysRoleDO getRole(Long id);
/**
* 获得角色分页
*
* @param reqVO 角色分页查询
* @return 角色分页结果
*/
PageResult<SysRoleDO> getRolePage(SysRolePageReqVO reqVO);
/**
* 获得角色列表
*
* @param reqVO 列表查询
* @return 角色列表
*/
List<SysRoleDO> getRoles(SysRoleExportReqVO reqVO);
}

View File

@@ -15,6 +15,7 @@ import cn.iocoder.dashboard.modules.system.redis.mq.producer.permission.SysMenuP
import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
@@ -127,46 +128,6 @@ public class SysMenuServiceImpl implements SysMenuService {
return menuMapper.selectList();
}
@Override
public List<SysMenuDO> listMenus() {
return menuMapper.selectList();
}
@Override
public List<SysMenuDO> listMenus(SysMenuListReqVO reqVO) {
return menuMapper.selectList(reqVO);
}
@Override
public List<SysMenuDO> listMenusFromCache(Collection<Integer> menuTypes, Collection<Integer> menusStatuses) {
// 任一一个参数为空,则返回空
if (CollectionUtils.isAnyEmpty(menuTypes, menusStatuses)) {
return Collections.emptyList();
}
// 创建新数组,避免缓存被修改
return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@Override
public List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds, Collection<Integer> menuTypes,
Collection<Integer> menusStatuses) {
// 任一一个参数为空,则返回空
if (CollectionUtils.isAnyEmpty(menuIds, menuTypes, menusStatuses)) {
return Collections.emptyList();
}
return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getId())
&& menuTypes.contains(menu.getType())
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@Override
public List<SysMenuDO> getMenuListByPermissionFromCache(String permission) {
return new ArrayList<>(permissionMenuCache.get(permission));
}
@Override
public Long createMenu(SysMenuCreateReqVO reqVO) {
// 校验父菜单存在
@@ -208,10 +169,6 @@ public class SysMenuServiceImpl implements SysMenuService {
*/
@Transactional(rollbackFor = Exception.class)
public void deleteMenu(Long menuId) {
// 校验更新的菜单是否存在
if (menuMapper.selectById(menuId) == null) {
throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS);
}
// 校验是否还有子菜单
if (menuMapper.selectCountByParentId(menuId) > 0) {
throw ServiceExceptionUtil.exception(MENU_EXISTS_CHILDREN);
@@ -235,6 +192,46 @@ public class SysMenuServiceImpl implements SysMenuService {
});
}
@Override
public List<SysMenuDO> getMenus() {
return menuMapper.selectList();
}
@Override
public List<SysMenuDO> getMenus(SysMenuListReqVO reqVO) {
return menuMapper.selectList(reqVO);
}
@Override
public List<SysMenuDO> listMenusFromCache(Collection<Integer> menuTypes, Collection<Integer> menusStatuses) {
// 任一一个参数为空,则返回空
if (CollectionUtils.isAnyEmpty(menuTypes, menusStatuses)) {
return Collections.emptyList();
}
// 创建新数组,避免缓存被修改
return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@Override
public List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds, Collection<Integer> menuTypes,
Collection<Integer> menusStatuses) {
// 任一一个参数为空,则返回空
if (CollectionUtils.isAnyEmpty(menuIds, menuTypes, menusStatuses)) {
return Collections.emptyList();
}
return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getId())
&& menuTypes.contains(menu.getType())
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@Override
public List<SysMenuDO> getMenuListByPermissionFromCache(String permission) {
return new ArrayList<>(permissionMenuCache.get(permission));
}
@Override
public SysMenuDO getMenu(Long id) {
return menuMapper.selectById(id);
@@ -250,7 +247,8 @@ public class SysMenuServiceImpl implements SysMenuService {
* @param parentId 父菜单编号
* @param childId 当前菜单编号
*/
private void checkParentResource(Long parentId, Long childId) {
@VisibleForTesting
public void checkParentResource(Long parentId, Long childId) {
if (parentId == null || MenuIdEnum.ROOT.getId().equals(parentId)) {
return;
}
@@ -279,7 +277,8 @@ public class SysMenuServiceImpl implements SysMenuService {
* @param parentId 父菜单编号
* @param id 菜单编号
*/
private void checkResource(Long parentId, String name, Long id) {
@VisibleForTesting
public void checkResource(Long parentId, String name, Long id) {
SysMenuDO menu = menuMapper.selectByParentIdAndName(parentId, name);
if (menu == null) {
return;

View File

@@ -86,6 +86,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
@Override
@PostConstruct
public void initLocalCache() {
Date now = new Date();
// 获取角色与菜单的关联列表,如果有更新
List<SysRoleMenuDO> roleMenuList = this.loadRoleMenuIfUpdate(maxUpdateTime);
if (CollUtil.isEmpty(roleMenuList)) {
@@ -102,7 +103,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
roleMenuCache = roleMenuCacheBuilder.build();
menuRoleCache = menuRoleCacheBuilder.build();
assert roleMenuList.size() > 0; // 断言,避免告警
maxUpdateTime = roleMenuList.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime();
maxUpdateTime = now;
log.info("[initLocalCache][初始化角色与菜单的关联数量为 {}]", roleMenuList.size());
}
@@ -123,7 +124,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
log.info("[loadRoleMenuIfUpdate][首次加载全量角色与菜单的关联]");
} else { // 判断数据库中是否有更新的角色与菜单的关联
if (!roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime)) {
if (Objects.isNull(roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime))) {
return null;
}
log.info("[loadRoleMenuIfUpdate][增量加载全量角色与菜单的关联]");
@@ -133,14 +134,14 @@ public class SysPermissionServiceImpl implements SysPermissionService {
}
@Override
public List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
Collection<Integer> menusStatuses) {
public List<SysMenuDO> getRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes,
Collection<Integer> menusStatuses) {
// 任一一个参数为空时,不返回任何菜单
if (CollectionUtils.isAnyEmpty(roleIds, menusStatuses, menusStatuses)) {
return Collections.emptyList();
}
// 判断角色是否包含管理员
List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds);
List<SysRoleDO> roleList = roleService.getRolesFromCache(roleIds);
boolean hasAdmin = roleService.hasAnyAdmin(roleList);
// 获得角色拥有的菜单关联
if (hasAdmin) { // 管理员,获取到全部
@@ -168,7 +169,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
// 如果是管理员的情况下,获取全部菜单编号
SysRoleDO role = roleService.getRole(roleId);
if (roleService.hasAnyAdmin(Collections.singletonList(role))) {
return CollectionUtils.convertSet(menuService.listMenus(), SysMenuDO::getId);
return CollectionUtils.convertSet(menuService.getMenus(), SysMenuDO::getId);
}
// 如果是非管理员的情况下,获得拥有的菜单编号
return CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId),
@@ -231,22 +232,41 @@ public class SysPermissionServiceImpl implements SysPermissionService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public void processRoleDeleted(Long roleId) {
// TODO 实现我
// // 标记删除 RoleResource
// roleResourceMapper.deleteByRoleId(roleId);
// // 标记删除 AdminRole
// adminRoleMapper.deleteByRoleId(roleId);
// 标记删除 UserRole
userRoleMapper.deleteListByRoleId(roleId);
// 标记删除 RoleMenu
roleMenuMapper.deleteListByRoleId(roleId);
// 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
permissionProducer.sendRoleMenuRefreshMessage();
}
});
}
@Override
@Transactional(rollbackFor = Exception.class)
public void processMenuDeleted(Long menuId) {
// TODO 实现我
roleMenuMapper.deleteListByMenuId(menuId);
// 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
permissionProducer.sendRoleMenuRefreshMessage();
}
});
}
@Override
public void processUserDeleted(Long userId) {
// TODO 实现我
userRoleMapper.deleteListByUserId(userId);
}
@Override
@@ -305,7 +325,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
if (roleService.hasAnyAdmin(roleIds)) {
return true;
}
Set<String> userRoles = CollectionUtils.convertSet(roleService.listRolesFromCache(roleIds),
Set<String> userRoles = CollectionUtils.convertSet(roleService.getRolesFromCache(roleIds),
SysRoleDO::getCode);
return CollUtil.containsAny(userRoles, Sets.newHashSet(roles));
}

View File

@@ -118,33 +118,6 @@ public class SysRoleServiceImpl implements SysRoleService {
return roleMapper.selectList();
}
@Override
public SysRoleDO getRoleFromCache(Long id) {
return roleCache.get(id);
}
@Override
public List<SysRoleDO> listRoles(@Nullable Collection<Integer> statuses) {
return roleMapper.selectListByStatus(statuses);
}
@Override
public List<SysRoleDO> listRolesFromCache(Collection<Long> ids) {
if (CollectionUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return roleCache.values().stream().filter(roleDO -> ids.contains(roleDO.getId()))
.collect(Collectors.toList());
}
@Override
public boolean hasAnyAdmin(Collection<SysRoleDO> roleList) {
if (CollectionUtil.isEmpty(roleList)) {
return false;
}
return roleList.stream().anyMatch(roleDO -> RoleCodeEnum.ADMIN.getKey().equals(roleDO.getCode()));
}
@Override
public Long createRole(SysRoleCreateReqVO reqVO) {
// 校验角色
@@ -173,41 +146,6 @@ public class SysRoleServiceImpl implements SysRoleService {
roleProducer.sendRoleRefreshMessage();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteRole(Long id) {
// 校验是否可以更新
this.checkUpdateRole(id);
// 标记删除
roleMapper.deleteById(id);
// 删除相关数据
permissionService.processRoleDeleted(id);
// 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
roleProducer.sendRoleRefreshMessage();
}
});
}
@Override
public SysRoleDO getRole(Long id) {
return roleMapper.selectById(id);
}
@Override
public PageResult<SysRoleDO> pageRole(SysRolePageReqVO reqVO) {
return roleMapper.selectPage(reqVO);
}
@Override
public List<SysRoleDO> listRoles(SysRoleExportReqVO reqVO) {
return roleMapper.listRoles(reqVO);
}
@Override
public void updateRoleStatus(Long id, Integer status) {
// 校验是否可以更新
@@ -235,6 +173,68 @@ public class SysRoleServiceImpl implements SysRoleService {
roleProducer.sendRoleRefreshMessage();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteRole(Long id) {
// 校验是否可以更新
this.checkUpdateRole(id);
// 标记删除
roleMapper.deleteById(id);
// 删除相关数据
permissionService.processRoleDeleted(id);
// 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
roleProducer.sendRoleRefreshMessage();
}
});
}
@Override
public SysRoleDO getRoleFromCache(Long id) {
return roleCache.get(id);
}
@Override
public List<SysRoleDO> getRoles(@Nullable Collection<Integer> statuses) {
return roleMapper.selectListByStatus(statuses);
}
@Override
public List<SysRoleDO> getRolesFromCache(Collection<Long> ids) {
if (CollectionUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return roleCache.values().stream().filter(roleDO -> ids.contains(roleDO.getId()))
.collect(Collectors.toList());
}
@Override
public boolean hasAnyAdmin(Collection<SysRoleDO> roleList) {
if (CollectionUtil.isEmpty(roleList)) {
return false;
}
return roleList.stream().anyMatch(roleDO -> RoleCodeEnum.ADMIN.getKey().equals(roleDO.getCode()));
}
@Override
public SysRoleDO getRole(Long id) {
return roleMapper.selectById(id);
}
@Override
public PageResult<SysRoleDO> getRolePage(SysRolePageReqVO reqVO) {
return roleMapper.selectPage(reqVO);
}
@Override
public List<SysRoleDO> getRoles(SysRoleExportReqVO reqVO) {
return roleMapper.listRoles(reqVO);
}
/**
* 校验角色的唯一字段是否重复
*
@@ -278,16 +278,10 @@ public class SysRoleServiceImpl implements SysRoleService {
}
}
// /**
// * 根据条件分页查询角色数据
// *
// * @param role 角色信息
// * @return 角色数据集合信息
// */
// @Override
// @DataScope(deptAlias = "d")
// public List<SysRole> selectRoleList(SysRole role) {
// return roleMapper.selectRoleList(role);
// }
}

View File

@@ -2,12 +2,13 @@ package cn.iocoder.dashboard.modules.system.service.user;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
@@ -25,75 +26,6 @@ import java.util.Map;
*/
public interface SysUserService {
/**
* 通过用户名查询用户
*
* @param username 用户名
* @return 用户对象信息
*/
SysUserDO getUserByUserName(String username);
/**
* 通过用户 ID 查询用户
*
* @param id 用户ID
* @return 用户对象信息
*/
SysUserDO getUser(Long id);
/**
* 获得用户分页列表
*
* @param reqVO 分页条件
* @return 分页列表
*/
PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO);
/**
* 获得用户列表
*
* @param reqVO 列表请求
* @return 用户列表
*/
List<SysUserDO> listUsers(SysUserExportReqVO reqVO);
/**
* 获得用户列表
*
* @param ids 用户编号数组
* @return 用户列表
*/
List<SysUserDO> listUsers(Collection<Long> ids);
/**
* 获得用户 Map
*
* @param ids 用户编号数组
* @return 用户 Map
*/
default Map<Long, SysUserDO> getUserMap(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return new HashMap<>();
}
return CollectionUtils.convertMap(listUsers(ids), SysUserDO::getId);
}
/**
* 获得用户列表,基于昵称模糊匹配
*
* @param nickname 昵称
* @return 用户列表
*/
List<SysUserDO> listUsersByNickname(String nickname);
/**
* 获得用户列表,基于用户账号模糊匹配
*
* @param username 用户账号
* @return 用户列表
*/
List<SysUserDO> listUsersByUsername(String username);
/**
* 创建用户
*
@@ -112,17 +44,26 @@ public interface SysUserService {
/**
* 修改用户个人信息
*
* @param id 用户编号
* @param reqVO 用户个人信息
* @return 修改结果
*/
void updateUserProfile(SysUserProfileUpdateReqVO reqVO);
void updateUserProfile(Long id, SysUserProfileUpdateReqVO reqVO);
/**
* 删除用户
* 修改用户个人密码
*
* @param id 用户编号
* @param reqVO 更新用户个人密码
*/
void deleteUser(Long id);
void updateUserPassword(Long id, SysUserProfileUpdatePasswordReqVO reqVO);
/**
* 更新用户头像
*
* @param id 用户 id
* @param avatarFile 头像文件
*/
void updateUserAvatar(Long id, InputStream avatarFile);
/**
* 修改密码
@@ -140,6 +81,82 @@ public interface SysUserService {
*/
void updateUserStatus(Long id, Integer status);
/**
* 删除用户
*
* @param id 用户编号
*/
void deleteUser(Long id);
/**
* 通过用户名查询用户
*
* @param username 用户名
* @return 用户对象信息
*/
SysUserDO getUserByUsername(String username);
/**
* 通过用户 ID 查询用户
*
* @param id 用户ID
* @return 用户对象信息
*/
SysUserDO getUser(Long id);
/**
* 获得用户分页列表
*
* @param reqVO 分页条件
* @return 分页列表
*/
PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO);
/**
* 获得用户列表
*
* @param reqVO 列表请求
* @return 用户列表
*/
List<SysUserDO> getUsers(SysUserExportReqVO reqVO);
/**
* 获得用户列表
*
* @param ids 用户编号数组
* @return 用户列表
*/
List<SysUserDO> getUsers(Collection<Long> ids);
/**
* 获得用户 Map
*
* @param ids 用户编号数组
* @return 用户 Map
*/
default Map<Long, SysUserDO> getUserMap(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return new HashMap<>();
}
return CollectionUtils.convertMap(getUsers(ids), SysUserDO::getId);
}
/**
* 获得用户列表,基于昵称模糊匹配
*
* @param nickname 昵称
* @return 用户列表
*/
List<SysUserDO> getUsersByNickname(String nickname);
/**
* 获得用户列表,基于用户账号模糊匹配
*
* @param username 用户账号
* @return 用户列表
*/
List<SysUserDO> getUsersByUsername(String username);
/**
* 批量导入用户
*
@@ -149,47 +166,4 @@ public interface SysUserService {
*/
SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport);
/**
* 更新用户头像
*
* @param id 用户 id
* @param avatarFile 头像文件
*/
void updateAvatar(Long id, InputStream avatarFile);
//
// /**
// * 修改用户基本信息
// *
// * @param user 用户信息
// * @return 结果
// */
// public int updateUserProfile(SysUser user);
//
// /**
// * 修改用户头像
// *
// * @param userName 用户名
// * @param avatar 头像地址
// * @return 结果
// */
// public boolean updateUserAvatar(String userName, String avatar);
//
// /**
// * 重置用户密码
// *
// * @param user 用户信息
// * @return 结果
// */
// public int resetPwd(SysUser user);
//
// /**
// * 重置用户密码
// *
// * @param userName 用户名
// * @param password 密码
// * @return 结果
// */
// public int resetUserPwd(String userName, String password);
}

View File

@@ -9,12 +9,13 @@ import cn.iocoder.dashboard.common.exception.ServiceException;
import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
@@ -61,64 +62,11 @@ public class SysUserServiceImpl implements SysUserService {
private SysPostService postService;
@Resource
private SysPermissionService permissionService;
@Resource
private PasswordEncoder passwordEncoder;
@Resource
private InfFileService fileService;
@Override
public SysUserDO getUserByUserName(String username) {
return userMapper.selectByUsername(username);
}
@Override
public SysUserDO getUser(Long id) {
return userMapper.selectById(id);
}
@Override
public PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO) {
return userMapper.selectPage(reqVO, this.getDeptCondition(reqVO.getDeptId()));
}
@Override
public List<SysUserDO> listUsers(SysUserExportReqVO reqVO) {
return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
}
@Override
public List<SysUserDO> listUsers(Collection<Long> ids) {
return userMapper.selectBatchIds(ids);
}
@Override
public List<SysUserDO> listUsersByNickname(String nickname) {
return userMapper.selectListByNickname(nickname);
}
@Override
public List<SysUserDO> listUsersByUsername(String username) {
return userMapper.selectListByUsername(username);
}
/**
* 获得部门条件:查询指定部门的子部门编号们,包括自身
*
* @param deptId 部门编号
* @return 部门编号集合
*/
private Set<Long> getDeptCondition(Long deptId) {
if (deptId == null) {
return Collections.emptySet();
}
Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache(
deptId, true), SysDeptDO::getId);
deptIds.add(deptId); // 包括自身
return deptIds;
}
@Override
public Long createUser(SysUserCreateReqVO reqVO) {
// 校验正确性
@@ -143,30 +91,35 @@ public class SysUserServiceImpl implements SysUserService {
}
@Override
public void updateUserProfile(SysUserProfileUpdateReqVO reqVO) {
public void updateUserProfile(Long id, SysUserProfileUpdateReqVO reqVO) {
// 校验正确性
this.checkUserExists(reqVO.getId());
this.checkEmailUnique(reqVO.getId(), reqVO.getEmail());
this.checkMobileUnique(reqVO.getId(), reqVO.getMobile());
// 校验填写密码
String encode = null;
if (this.checkOldPassword(reqVO.getId(), reqVO.getOldPassword(), reqVO.getNewPassword())) {
// 更新密码
encode = passwordEncoder.encode(reqVO.getNewPassword());
}
SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
if (StrUtil.isNotBlank(encode)) {
updateObj.setPassword(encode);
}
this.checkUserExists(id);
this.checkEmailUnique(id, reqVO.getEmail());
this.checkMobileUnique(id, reqVO.getMobile());
// 执行更新
userMapper.updateById(SysUserConvert.INSTANCE.convert(reqVO).setId(id));
}
@Override
public void updateUserPassword(Long id, SysUserProfileUpdatePasswordReqVO reqVO) {
// 校验旧密码密码
this.checkOldPassword(id, reqVO.getOldPassword());
// 执行更新
SysUserDO updateObj = new SysUserDO().setId(id);
updateObj.setPassword(passwordEncoder.encode(reqVO.getNewPassword())); // 加密密码
userMapper.updateById(updateObj);
}
@Override
public void deleteUser(Long id) {
// 校验用户存在
public void updateUserAvatar(Long id, InputStream avatarFile) {
this.checkUserExists(id);
// 删除用户
userMapper.deleteById(id);
// 存储文件
String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile));
// 更新路径
SysUserDO sysUserDO = new SysUserDO();
sysUserDO.setId(id);
sysUserDO.setAvatar(avatar);
userMapper.updateById(sysUserDO);
}
@Override
@@ -193,6 +146,65 @@ public class SysUserServiceImpl implements SysUserService {
permissionService.processUserDeleted(id);
}
@Override
public void deleteUser(Long id) {
// 校验用户存在
this.checkUserExists(id);
// 删除用户
userMapper.deleteById(id);
}
@Override
public SysUserDO getUserByUsername(String username) {
return userMapper.selectByUsername(username);
}
@Override
public SysUserDO getUser(Long id) {
return userMapper.selectById(id);
}
@Override
public PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO) {
return userMapper.selectPage(reqVO, this.getDeptCondition(reqVO.getDeptId()));
}
@Override
public List<SysUserDO> getUsers(SysUserExportReqVO reqVO) {
return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
}
@Override
public List<SysUserDO> getUsers(Collection<Long> ids) {
return userMapper.selectBatchIds(ids);
}
@Override
public List<SysUserDO> getUsersByNickname(String nickname) {
return userMapper.selectListByNickname(nickname);
}
@Override
public List<SysUserDO> getUsersByUsername(String username) {
return userMapper.selectListByUsername(username);
}
/**
* 获得部门条件:查询指定部门的子部门编号们,包括自身
*
* @param deptId 部门编号
* @return 部门编号集合
*/
private Set<Long> getDeptCondition(Long deptId) {
if (deptId == null) {
return Collections.emptySet();
}
Set<Long> deptIds = CollectionUtils.convertSet(deptService.getDeptsByParentIdFromCache(
deptId, true), SysDeptDO::getId);
deptIds.add(deptId); // 包括自身
return deptIds;
}
private void checkCreateOrUpdate(Long id, String username, String mobile, String email,
Long deptId, Set<Long> postIds) {
// 校验用户存在
@@ -287,7 +299,7 @@ public class SysUserServiceImpl implements SysUserService {
if (CollUtil.isEmpty(postIds)) { // 允许不选择
return;
}
List<SysPostDO> posts = postService.listPosts(postIds, null);
List<SysPostDO> posts = postService.getPosts(postIds, null);
if (CollUtil.isEmpty(posts)) {
throw ServiceExceptionUtil.exception(POST_NOT_FOUND);
}
@@ -304,26 +316,19 @@ public class SysUserServiceImpl implements SysUserService {
}
/**
* 校验旧密码、新密码
* 校验旧密码
*
* @param id 用户 id
* @param oldPassword 旧密码
* @param newPassword 新密码
* @return 校验结果
*/
private boolean checkOldPassword(Long id, String oldPassword, String newPassword) {
if (id == null || StrUtil.isBlank(oldPassword) || StrUtil.isBlank(newPassword)) {
return false;
}
private void checkOldPassword(Long id, String oldPassword) {
SysUserDO user = userMapper.selectById(id);
if (user == null) {
throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
}
if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED);
}
return true;
}
@Override
@@ -364,16 +369,4 @@ public class SysUserServiceImpl implements SysUserService {
return respVO;
}
@Override
public void updateAvatar(Long id, InputStream avatarFile) {
this.checkUserExists(id);
// 存储文件
String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile));
// 更新路径
SysUserDO sysUserDO = new SysUserDO();
sysUserDO.setId(id);
sysUserDO.setAvatar(avatar);
userMapper.updateById(sysUserDO);
}
}