对齐 boot 与 cloud 的代码

This commit is contained in:
YunaiV
2023-07-27 13:01:17 +08:00
parent 1475e9a507
commit 0feb865ef0
53 changed files with 413 additions and 237 deletions

View File

@@ -1,8 +1,7 @@
### 请求 /login 接口 => 成功
POST {{systemBaseUrl}}/system/auth/login
POST {{baseUrl}}/system/auth/login
Content-Type: application/json
tenant-id: {{adminTenentId}}
tag: {{tag}}
{
"username": "admin",
@@ -12,7 +11,7 @@ tag: {{tag}}
}
### 请求 /login 接口 => 成功(无验证码)
POST {{systemBaseUrl}}/system/auth/login
POST {{baseUrl}}/system/auth/login
Content-Type: application/json
tenant-id: {{adminTenentId}}
@@ -22,12 +21,12 @@ tenant-id: {{adminTenentId}}
}
### 请求 /get-permission-info 接口 => 成功
GET {{systemBaseUrl}}/system/auth/get-permission-info
GET {{baseUrl}}/system/auth/get-permission-info
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
### 请求 /list-menus 接口 => 成功
GET {{systemBaseUrl}}/system/auth/list-menus
#Authorization: Bearer {{token}}
Authorization: Bearer c347026e805e4d99b0d116eae66eda8c
GET {{baseUrl}}/system/list-menus
Authorization: Bearer {{token}}
#Authorization: Bearer a6aa7714a2e44c95aaa8a2c5adc2a67a
tenant-id: {{adminTenentId}}

View File

@@ -14,7 +14,7 @@ import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
@Schema(description = "管理后台 - 账号密码登录 Request VO,如果登录并绑定社交用户,需要传递 social 开头的参数")
@Schema(description = "管理后台 - 账号密码登录 Request VO如果登录并绑定社交用户,需要传递 social 开头的参数")
@Data
@NoArgsConstructor
@AllArgsConstructor
@@ -34,7 +34,7 @@ public class AuthLoginReqVO {
// ========== 图片验证码相关 ==========
@Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED,
@Schema(description = "验证码验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED,
example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==")
@NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class)
private String captchaVerification;
@@ -54,8 +54,7 @@ public class AuthLoginReqVO {
/**
* 开启验证码的 Group
*/
public interface CodeEnableGroup {
}
public interface CodeEnableGroup {}
@AssertTrue(message = "授权码不能为空")
public boolean isSocialCodeValid() {

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.controller.admin.auth.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -38,7 +37,7 @@ public class AuthPermissionInfoRespVO {
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
private String nickname;
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://www.iocoder.cn/xx.jpg")
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg")
private String avatar;
}

View File

@@ -6,17 +6,17 @@ import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO;
import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -34,6 +34,28 @@ public class AreaController {
return success(AreaConvert.INSTANCE.convertList(area.getChildren()));
}
@GetMapping("/get-children")
@Operation(summary = "获得地区的下级区域")
@Parameter(name = "id", description = "区域编号", required = true, example = "150000")
public CommonResult<List<AreaNodeSimpleRespVO>> getChildren(@RequestParam("id") Integer id) {
Area area = AreaUtils.getArea(id);
Assert.notNull(area, String.format("获取不到 id : %d 的区域", id));
return success(AreaConvert.INSTANCE.convertList2(area.getChildren()));
}
// 4)方法改成 getAreaChildrenList 获得子节点们5url 可以已改成 children-list
//@芋艿 是不是叫 getAreaListByIds 更合适。 因为不一定是子节点。 用于前端树选择获取缓存数据。 见 <el-tree-select :cache-data="areaCache">
@GetMapping("/get-by-ids")
@Operation(summary = "通过区域 ids 获得地区列表")
@Parameter(name = "ids", description = "区域编号 ids", required = true, example = "1,150000")
public CommonResult<List<AreaNodeSimpleRespVO>> getAreaListByIds(@RequestParam("ids") Set<Integer> ids) {
List<Area> areaList = new ArrayList<>(ids.size());
for (Integer areaId : ids) {
areaList.add(AreaUtils.getArea(areaId));
}
return success(AreaConvert.INSTANCE.convertList2(areaList));
}
@GetMapping("/get-by-ip")
@Operation(summary = "获得 IP 对应的地区名")
@Parameter(name = "ip", description = "IP", required = true)

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.controller.admin.ip.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.system.controller.admin.ip.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 简洁的地区节点 Response VO")
@Data
public class AreaNodeSimpleRespVO {
@Schema(description = "编号", required = true, example = "110000")
private Integer id;
@Schema(description = "名字", required = true, example = "北京")
private String name;
@Schema(description = "是否叶子节点", required = false, example = "false")
private Boolean leaf;
}

View File

@@ -9,9 +9,9 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 站内信模版 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
* 站内信模版 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class NotifyTemplateBaseVO {

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -17,7 +16,7 @@ public class OAuth2UserInfoRespVO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
private String username;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")

View File

@@ -31,7 +31,7 @@ tenant-id: {{adminTenentId}}
roleId=14
### /role/get 成功
GET {{systemBaseUrl}}/system/role/get?id=100
GET {{baseUrl}}/system/role/get?id=100
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
@@ -40,6 +40,3 @@ tenant-id: {{adminTenentId}}
GET {{baseUrl}}/system/role/page?pageNo=1&pageSize=10
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
###

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -12,8 +11,8 @@ import java.util.Set;
@Data
public class PermissionAssignUserRoleReqVO {
@Schema(description = "角色编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "角色编号不能为空")
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "角色编号列表", example = "1,3,5")

View File

@@ -1,5 +1,5 @@
### 请求 /system/sms-template/send-sms 接口 => 成功
POST {{systemBaseUrl}}/system/sms-template/send-sms
POST {{baseUrl}}/system/sms-template/send-sms
Authorization: Bearer {{token}}
Content-Type: application/json
tenant-id: {{adminTenentId}}

View File

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.log;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@@ -31,14 +30,14 @@ public class SmsLogPageReqVO extends PageParam {
private Integer sendStatus;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "开始发送时间")
@Schema(description = "发送时间")
private LocalDateTime[] sendTime;
@Schema(description = "接收状态,参见 SmsSendStatusEnum 枚举类", example = "0")
@Schema(description = "接收状态,参见 SmsReceiveStatusEnum 枚举类", example = "0")
private Integer receiveStatus;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "开始接收时间")
@Schema(description = "接收时间")
private LocalDateTime[] receiveTime;
}

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -26,11 +25,11 @@ public class UserExportReqVO {
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "部门编号,同时筛选子部门", example = "1024")
private Long deptId;
}
}

View File

@@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@@ -1,12 +1,11 @@
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Schema(description = "用户精简信息 Response VO")
@Schema(description = "管理后台 - 用户精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor

View File

@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -16,7 +17,7 @@ public class UserUpdateStatusReqVO {
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
// @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}

View File

@@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.system.controller.app.ip;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 App - 地区")
@RestController
@RequestMapping("/system/area")
@Validated
public class AppAreaController {
@GetMapping("/tree")
@Operation(summary = "获得地区树")
public CommonResult<List<AppAreaNodeRespVO>> getAreaTree() {
Area area = AreaUtils.getArea(Area.ID_CHINA);
Assert.notNull(area, "获取不到中国");
return success(AreaConvert.INSTANCE.convertList3(area.getChildren()));
}
}

View File

@@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.system.controller.app.ip.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "用户 App - 地区节点 Response VO")
@Data
public class AppAreaNodeRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000")
private Integer id;
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "北京")
private String name;
/**
* 子节点
*/
private List<AppAreaNodeRespVO> children;
}

View File

@@ -27,10 +27,10 @@ public interface AuthConvert {
default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
return AuthPermissionInfoRespVO.builder()
.user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build())
.roles(convertSet(roleList, RoleDO::getCode))
.permissions(convertSet(menuList, MenuDO::getPermission))
.build();
.user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build())
.roles(convertSet(roleList, RoleDO::getCode))
.permissions(convertSet(menuList, MenuDO::getPermission))
.build();
}
AuthMenuRespVO convertTreeNode(MenuDO menu);

View File

@@ -1,11 +1,16 @@
package cn.iocoder.yudao.module.system.convert.ip;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO;
import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Objects;
@Mapper
public interface AreaConvert {
@@ -14,4 +19,15 @@ public interface AreaConvert {
List<AreaNodeRespVO> convertList(List<Area> list);
List<AreaNodeSimpleRespVO> convertList2(List<Area> list);
@Mapping(source = "type", target = "leaf")
AreaNodeSimpleRespVO convert(Area area);
default Boolean convertAreaType(Integer type) {
return Objects.equals(AreaTypeEnum.DISTRICT.getType(), type);
}
List<AppAreaNodeRespVO> convertList3(List<Area> list);
}

View File

@@ -140,9 +140,9 @@ public class DeptServiceImpl implements DeptService {
}
List<DeptDO> result = new ArrayList<>();
// 递归,简单粗暴
getDeptsByParentIdFromCache(result, parentId,
recursive ? Integer.MAX_VALUE : 1, // 如果递归获取,则无限;否则,只递归 1 次
parentDeptCache);
getDeptsByParentIdFromCache(result, parentId,
recursive ? Integer.MAX_VALUE : 1, // 如果递归获取,则无限;否则,只递归 1 次
parentDeptCache);
return result;
}

View File

@@ -185,7 +185,7 @@ public class MenuServiceImpl implements MenuService {
}
// 创建新数组,避免缓存被修改
return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
&& menusStatuses.contains(menu.getStatus()))
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@@ -238,7 +238,7 @@ public class MenuServiceImpl implements MenuService {
}
// 父菜单必须是目录或者菜单类型
if (!MenuTypeEnum.DIR.getType().equals(menu.getType())
&& !MenuTypeEnum.MENU.getType().equals(menu.getType())) {
&& !MenuTypeEnum.MENU.getType().equals(menu.getType())) {
throw exception(MENU_PARENT_NOT_DIR_OR_MENU);
}
}

View File

@@ -171,8 +171,8 @@ public class RoleServiceImpl implements RoleService {
@Override
public List<RoleDO> getRoleListByStatus(@Nullable Collection<Integer> statuses) {
if (CollUtil.isEmpty(statuses)) {
return roleMapper.selectList();
}
return roleMapper.selectList();
}
return roleMapper.selectListByStatus(statuses);
}

View File

@@ -349,8 +349,9 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
// 调用
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
// 校验调用参数
verify(loginLogService).createLoginLog(argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
verify(loginLogService).createLoginLog(
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
);
// 调用,并校验

View File

@@ -33,7 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
class MailSendServiceImplTest extends BaseMockitoUnitTest {
public class MailSendServiceImplTest extends BaseMockitoUnitTest {
@InjectMocks
private MailSendServiceImpl mailSendService;
@@ -278,16 +278,17 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest {
// mock 方法(发送邮件)
String messageId = randomString();
mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> {
assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom());
assertTrue(mailAccount.isAuth());
assertEquals(account.getUsername(), mailAccount.getUser());
assertEquals(account.getPassword(), mailAccount.getPass());
assertEquals(account.getHost(), mailAccount.getHost());
assertEquals(account.getPort(), mailAccount.getPort());
assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
return true;
}), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true)))
mailUtilMock.when(() -> MailUtil.send(
argThat(mailAccount -> {
assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom());
assertTrue(mailAccount.isAuth());
assertEquals(account.getUsername(), mailAccount.getUser());
assertEquals(account.getPassword(), mailAccount.getPass());
assertEquals(account.getHost(), mailAccount.getHost());
assertEquals(account.getPort(), mailAccount.getPort());
assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
return true;
}), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true)))
.thenReturn(messageId);
// 调用

View File

@@ -454,7 +454,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
TenantContextHolder.setTenantId(dbTenant.getId());
// mock 菜单
when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)),
randomPojo(MenuDO.class, o -> o.setId(101L))));
randomPojo(MenuDO.class, o -> o.setId(101L))));
// 调用
tenantService.handleTenantMenu(handler);