【更新】完善移动端菜单模块,增加按钮模块,与PC一致

This commit is contained in:
xuyuxiang 2023-02-01 10:11:18 +08:00
parent fed5dc8bbf
commit e288a19078
29 changed files with 846 additions and 20 deletions

View File

@ -98,6 +98,14 @@ public interface SaBaseLoginUserApi {
*/
List<String> getButtonCodeListListByUserId(String userId);
/**
* 根据用户id获取移动端按钮码集合
*
* @author xuyuxiang
* @date 2022/4/27 22:54
*/
List<String> getMobileButtonCodeListListByUserId(String userId);
/**
* 根据用户id获取权限集合
*

View File

@ -189,20 +189,24 @@ public abstract class SaBaseClientLoginUser {
@ApiModelProperty(value = "按钮码集合", position = 40)
private List<String> buttonCodeList;
/** 移动端按钮码集合 */
@ApiModelProperty(value = "移动端按钮码集合", position = 41)
private List<String> mobileButtonCodeList;
/** 权限码集合 */
@ApiModelProperty(value = "权限码集合", position = 41, hidden = true)
@ApiModelProperty(value = "权限码集合", position = 42, hidden = true)
private List<String> permissionCodeList;
/** 角色码集合 */
@ApiModelProperty(value = "角色码集合", position = 42, hidden = true)
@ApiModelProperty(value = "角色码集合", position = 43, hidden = true)
private List<String> roleCodeList;
/** 数据范围集合 */
@ApiModelProperty(value = "数据范围集合", position = 43, hidden = true)
private List<SaBaseClientLoginUser.DataScope> dataScopeList;
@ApiModelProperty(value = "数据范围集合", position = 44, hidden = true)
private List<DataScope> dataScopeList;
/** 用户密码hash值 */
@ApiModelProperty(value = "用户密码hash值", position = 44)
@ApiModelProperty(value = "用户密码hash值", position = 45)
private String password;
/** 是否可登录,由继承类实现 */

View File

@ -225,20 +225,24 @@ public abstract class SaBaseLoginUser {
@ApiModelProperty(value = "按钮码集合", position = 50)
private List<String> buttonCodeList;
/** 移动端按钮码集合 */
@ApiModelProperty(value = "移动端按钮码集合", position = 51)
private List<String> mobileButtonCodeList;
/** 权限码集合 */
@ApiModelProperty(value = "权限码集合", position = 51, hidden = true)
@ApiModelProperty(value = "权限码集合", position = 52, hidden = true)
private List<String> permissionCodeList;
/** 角色码集合 */
@ApiModelProperty(value = "角色码集合", position = 52, hidden = true)
@ApiModelProperty(value = "角色码集合", position = 53, hidden = true)
private List<String> roleCodeList;
/** 数据范围集合 */
@ApiModelProperty(value = "数据范围集合", position = 53, hidden = true)
@ApiModelProperty(value = "数据范围集合", position = 54, hidden = true)
private List<DataScope> dataScopeList;
/** 用户密码hash值 */
@ApiModelProperty(value = "用户密码hash值", position = 54)
@ApiModelProperty(value = "用户密码hash值", position = 55)
private String password;
/** 是否可登录,由继承类实现 */

View File

@ -0,0 +1,23 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.api;
/**
* 移动端按钮API
*
* @author xuyuxiang
* @date 2023/2/1 9:52
**/
public interface MobileButtonApi {
}

View File

@ -36,5 +36,13 @@ public interface SysRelationApi {
* @author xuyuxiang
* @date 2023/1/31 9:54
**/
void removeRoleHasMobileMenuRelationByMenuIdList(List<String> targetIdList);
void removeRoleHasMobileMenuRelation(List<String> targetIdList);
/**
* 清除对应的角色与移动端菜单信息中的授权的移动端按钮信息
*
* @author xuyuxiang
* @date 2023/1/31 9:54
**/
void removeRoleHasMobileButtonRelation(List<String> targetIdList, List<String> buttonIdList);
}

View File

@ -284,6 +284,8 @@ public class AuthServiceImpl implements AuthService {
StpUtil.login(saBaseLoginUser.getId(), new SaLoginModel().setDevice(device));
// 获取按钮码
saBaseLoginUser.setButtonCodeList(loginUserApi.getButtonCodeListListByUserId(saBaseLoginUser.getId()));
// 获取移动端按钮码
saBaseLoginUser.setMobileButtonCodeList(loginUserApi.getMobileButtonCodeListListByUserId(saBaseLoginUser.getId()));
// 获取数据范围
saBaseLoginUser.setDataScopeList(Convert.toList(SaBaseLoginUser.DataScope.class,
loginUserApi.getPermissionListByUserId(saBaseLoginUser.getId(), saBaseLoginUser.getOrgId())));
@ -313,6 +315,8 @@ public class AuthServiceImpl implements AuthService {
StpClientUtil.login(saBaseClientLoginUser.getId(), new SaLoginModel().setDevice(device));
// 获取按钮码
saBaseClientLoginUser.setButtonCodeList(clientLoginUserApi.getButtonCodeListListByUserId(saBaseClientLoginUser.getId()));
// 获取移动端按钮码
saBaseClientLoginUser.setMobileButtonCodeList(clientLoginUserApi.getMobileButtonCodeListListByUserId(saBaseClientLoginUser.getId()));
// 获取数据范围
saBaseClientLoginUser.setDataScopeList(Convert.toList(SaBaseClientLoginUser.DataScope.class,
clientLoginUserApi.getPermissionListByUserId(saBaseClientLoginUser.getId(), null)));

View File

@ -139,6 +139,18 @@ public class ClientLoginUserApiProvider implements SaBaseLoginUserApi {
return CollectionUtil.newArrayList();
}
/**
* 根据用户id获取移动端按钮码集合
*
* @author xuyuxiang
* @date 2022/4/27 22:54
*/
@Override
public List<String> getMobileButtonCodeListListByUserId(String userId) {
// TODO C端用户暂无移动端按钮码
return CollectionUtil.newArrayList();
}
/**
* 根据用户id获取权限集合
*

View File

@ -0,0 +1,123 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import vip.xiaonuo.common.annotation.CommonLog;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.mobile.modular.resource.entity.MobileButton;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonAddParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonEditParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonIdParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonPageParam;
import vip.xiaonuo.mobile.modular.resource.service.MobileButtonService;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
* 移动端按钮控制器
*
* @author xuyuxiang
* @date 2022/6/27 13:56
**/
@Api(tags = "移动端按钮控制器")
@ApiSupport(author = "SNOWY_TEAM", order = 3)
@RestController
@Validated
public class MobileButtonController {
@Resource
private MobileButtonService mobileButtonService;
/**
* 获取移动端按钮分页
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取移动端按钮分页")
@GetMapping("/mobile/button/page")
public CommonResult<Page<MobileButton>> page(MobileButtonPageParam mobileButtonPageParam) {
return CommonResult.data(mobileButtonService.page(mobileButtonPageParam));
}
/**
* 添加移动端按钮
*
* @author xuyuxiang
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 2)
@ApiOperation("添加移动端按钮")
@CommonLog("添加移动端按钮")
@PostMapping("/mobile/button/add")
public CommonResult<String> add(@RequestBody @Valid MobileButtonAddParam mobileButtonAddParam) {
mobileButtonService.add(mobileButtonAddParam);
return CommonResult.ok();
}
/**
* 编辑移动端按钮
*
* @author xuyuxiang
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("编辑移动端按钮")
@CommonLog("编辑移动端按钮")
@PostMapping("/mobile/button/edit")
public CommonResult<String> edit(@RequestBody @Valid MobileButtonEditParam mobileButtonEditParam) {
mobileButtonService.edit(mobileButtonEditParam);
return CommonResult.ok();
}
/**
* 删除移动端按钮
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 4)
@ApiOperation("删除移动端按钮")
@CommonLog("删除移动端按钮")
@PostMapping("/mobile/button/delete")
public CommonResult<String> delete(@RequestBody @Valid List<MobileButtonIdParam> mobileButtonIdParamList) {
mobileButtonService.delete(mobileButtonIdParamList);
return CommonResult.ok();
}
/**
* 获取移动端按钮详情
*
* @author xuyuxiang
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("获取移动端按钮详情")
@GetMapping("/mobile/button/detail")
public CommonResult<MobileButton> detail(@Valid MobileButtonIdParam mobileButtonIdParam) {
return CommonResult.data(mobileButtonService.detail(mobileButtonIdParam));
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.entity;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import vip.xiaonuo.common.pojo.CommonEntity;
/**
* 移动端按钮实体
*
* @author xuyuxiang
* @date 2022/7/27 18:25
**/
@Getter
@Setter
@TableName("MOBILE_RESOURCE")
public class MobileButton extends CommonEntity {
/** id */
@ApiModelProperty(value = "id", position = 1)
private String id;
/** 父id */
@ApiModelProperty(value = "父id", position = 2)
private String parentId;
/** 标题 */
@ApiModelProperty(value = "标题", position = 3)
private String title;
/** 编码 */
@ApiModelProperty(value = "编码", position = 4)
private String code;
/** 分类 */
@ApiModelProperty(value = "分类", position = 5)
private String category;
/** 排序码 */
@ApiModelProperty(value = "排序码", position = 6)
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 7)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String extJson;
}

View File

@ -28,7 +28,10 @@ public enum MobileResourceCategoryEnum {
MODULE("MODULE"),
/** 菜单 */
MENU("MENU");
MENU("MENU"),
/** 按钮 */
BUTTON("BUTTON");
private final String value;

View File

@ -0,0 +1,25 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import vip.xiaonuo.mobile.modular.resource.entity.MobileButton;
/**
* 移动端按钮Mapper接口
*
* @author xuyuxiang
* @date 2022/4/21 18:37
**/
public interface MobileButtonMapper extends BaseMapper<MobileButton> {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="vip.xiaonuo.mobile.modular.resource.mapper.MobileButtonMapper">
</mapper>

View File

@ -2,5 +2,4 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="vip.xiaonuo.mobile.modular.resource.mapper.MobileModuleMapper">
</mapper>

View File

@ -0,0 +1,55 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 移动端按钮添加参数
*
* @author xuyuxiang
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class MobileButtonAddParam {
/** 父id */
@ApiModelProperty(value = "父id", required = true, position = 1)
@NotBlank(message = "parentId不能为空")
private String parentId;
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 2)
@NotBlank(message = "title不能为空")
private String title;
/** 编码 */
@ApiModelProperty(value = "编码", required = true, position = 3)
@NotBlank(message = "code不能为空")
private String code;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 4)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展JSON */
@ApiModelProperty(value = "扩展JSON", position = 5)
private String extJson;
}

View File

@ -0,0 +1,60 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 移动端按钮编辑参数
*
* @author xuyuxiang
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class MobileButtonEditParam {
/** id */
@ApiModelProperty(value = "id", required = true, position = 1)
@NotBlank(message = "id不能为空")
private String id;
/** 父id */
@ApiModelProperty(value = "父id", required = true, position = 2)
@NotBlank(message = "parentId不能为空")
private String parentId;
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 3)
@NotBlank(message = "title不能为空")
private String title;
/** 编码 */
@ApiModelProperty(value = "编码", required = true, position = 4)
@NotBlank(message = "code不能为空")
private String code;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 5)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展JSON */
@ApiModelProperty(value = "扩展JSON", position = 6)
private String extJson;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 移动端按钮Id参数
*
* @author xuyuxiang
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class MobileButtonIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 移动端按钮查询参数
*
* @author xuyuxiang
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class MobileButtonPageParam {
/** 当前页 */
@ApiModelProperty(value = "当前页码")
private Integer current;
/** 每页条数 */
@ApiModelProperty(value = "每页条数")
private Integer size;
/** 排序字段 */
@ApiModelProperty(value = "排序字段字段驼峰名称userName")
private String sortField;
/** 排序方式 */
@ApiModelProperty(value = "排序方式升序ASCEND降序DESCEND")
private String sortOrder;
/** 父id */
@ApiModelProperty(value = "父id")
private String parentId;
/** 名称关键词 */
@ApiModelProperty(value = "名称关键词")
private String searchKey;
}

View File

@ -0,0 +1,27 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.provider;
import org.springframework.stereotype.Service;
import vip.xiaonuo.mobile.api.MobileButtonApi;
/**
* 移动端按钮API接口提供者
*
* @author xuyuxiang
* @date 2023/1/31 10:12
**/
@Service
public class MobileButtonApiProvider implements MobileButtonApi {
}

View File

@ -0,0 +1,80 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import vip.xiaonuo.mobile.modular.resource.entity.MobileButton;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonAddParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonEditParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonIdParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonPageParam;
import java.util.List;
/**
* 移动端按钮Service接口
*
* @author xuyuxiang
* @date 2022/6/27 14:01
**/
public interface MobileButtonService extends IService<MobileButton> {
/**
* 获取移动端按钮分页
*
* @author xuyuxiang
* @date 2022/4/24 20:08
*/
Page<MobileButton> page(MobileButtonPageParam mobileButtonPageParam);
/**
* 添加移动端按钮
*
* @author xuyuxiang
* @date 2022/4/24 20:48
*/
void add(MobileButtonAddParam mobileButtonAddParam);
/**
* 编辑移动端按钮
*
* @author xuyuxiang
* @date 2022/4/24 21:13
*/
void edit(MobileButtonEditParam mobileButtonEditParam);
/**
* 删除移动端按钮
*
* @author xuyuxiang
* @date 2022/4/24 21:18
*/
void delete(List<MobileButtonIdParam> mobileButtonIdParamList);
/**
* 获取移动端按钮详情
*
* @author xuyuxiang
* @date 2022/4/24 21:18
*/
MobileButton detail(MobileButtonIdParam mobileButtonIdParam);
/**
* 获取移动端按钮详情
*
* @author xuyuxiang
* @date 2022/4/24 21:18
*/
MobileButton queryEntity(String id);
}

View File

@ -0,0 +1,135 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
*
* 1.请不要删除和修改根目录下的LICENSE文件
* 2.请不要删除和修改Snowy源码头部的版权声明
* 3.本项目代码可免费商业使用商业使用请保留源码和相关描述文件的项目出处作者声明等
* 4.分发源码时候请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package vip.xiaonuo.mobile.modular.resource.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.mobile.modular.resource.entity.MobileButton;
import vip.xiaonuo.mobile.modular.resource.entity.MobileMenu;
import vip.xiaonuo.mobile.modular.resource.enums.MobileResourceCategoryEnum;
import vip.xiaonuo.mobile.modular.resource.mapper.MobileButtonMapper;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonAddParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonEditParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonIdParam;
import vip.xiaonuo.mobile.modular.resource.param.button.MobileButtonPageParam;
import vip.xiaonuo.mobile.modular.resource.service.MobileButtonService;
import vip.xiaonuo.mobile.modular.resource.service.MobileMenuService;
import vip.xiaonuo.sys.api.SysRelationApi;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 移动端按钮Service接口实现类
*
* @author xuyuxiang
* @date 2022/6/27 14:25
**/
@Service
public class MobileButtonServiceImpl extends ServiceImpl<MobileButtonMapper, MobileButton> implements MobileButtonService {
@Resource
private SysRelationApi sysRelationApi;
@Resource
private MobileMenuService mobileMenuService;
@Override
public Page<MobileButton> page(MobileButtonPageParam mobileButtonPageParam) {
QueryWrapper<MobileButton> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(MobileButton::getCategory, MobileResourceCategoryEnum.BUTTON.getValue());
if(ObjectUtil.isNotEmpty(mobileButtonPageParam.getParentId())) {
queryWrapper.lambda().eq(MobileButton::getParentId, mobileButtonPageParam.getParentId());
}
if(ObjectUtil.isNotEmpty(mobileButtonPageParam.getSearchKey())) {
queryWrapper.lambda().like(MobileButton::getTitle, mobileButtonPageParam.getSearchKey());
}
if(ObjectUtil.isAllNotEmpty(mobileButtonPageParam.getSortField(), mobileButtonPageParam.getSortOrder())) {
CommonSortOrderEnum.validate(mobileButtonPageParam.getSortOrder());
queryWrapper.orderBy(true, mobileButtonPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(mobileButtonPageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(MobileButton::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Override
public void add(MobileButtonAddParam mobileButtonAddParam) {
MobileButton mobileButton = BeanUtil.toBean(mobileButtonAddParam, MobileButton.class);
boolean repeatCode = this.count(new LambdaQueryWrapper<MobileButton>()
.eq(MobileButton::getCategory, MobileResourceCategoryEnum.BUTTON.getValue())
.eq(MobileButton::getCode, mobileButton.getCode())) > 0;
if(repeatCode) {
throw new CommonException("存在重复的移动端按钮,编码为:{}", mobileButton.getCode());
}
mobileButton.setCategory(MobileResourceCategoryEnum.BUTTON.getValue());
this.save(mobileButton);
}
@Override
public void edit(MobileButtonEditParam mobileButtonEditParam) {
MobileButton mobileButton = this.queryEntity(mobileButtonEditParam.getId());
BeanUtil.copyProperties(mobileButtonEditParam, mobileButton);
boolean repeatCode = this.count(new LambdaQueryWrapper<MobileButton>()
.eq(MobileButton::getCategory, MobileResourceCategoryEnum.BUTTON.getValue())
.eq(MobileButton::getCode, mobileButton.getCode())
.ne(MobileButton::getId, mobileButtonEditParam.getId())) > 0;
if(repeatCode) {
throw new CommonException("存在重复的移动端按钮,编码为:{}", mobileButton.getCode());
}
this.updateById(mobileButton);
}
@Override
public void delete(List<MobileButtonIdParam> mobileButtonIdParamList) {
List<String> buttonIdList = CollStreamUtil.toList(mobileButtonIdParamList, MobileButtonIdParam::getId);
if(ObjectUtil.isNotEmpty(buttonIdList)) {
// 获取移动端按钮的父菜单id集合
List<String> parentMenuIdList = mobileMenuService.list(new LambdaQueryWrapper<MobileMenu>().in(MobileMenu::getId, buttonIdList)
.eq(MobileMenu::getCategory, MobileResourceCategoryEnum.BUTTON.getValue())).stream().map(MobileMenu::getParentId)
.collect(Collectors.toList());
if(ObjectUtil.isNotEmpty(parentMenuIdList)) {
// 清除对应的角色与移动端菜单信息中的授权的移动端按钮信息
sysRelationApi.removeRoleHasMobileButtonRelation(parentMenuIdList, buttonIdList);
// 执行删除
this.removeBatchByIds(buttonIdList);
}
}
}
@Override
public MobileButton detail(MobileButtonIdParam mobileButtonIdParam) {
return this.queryEntity(mobileButtonIdParam.getId());
}
@Override
public MobileButton queryEntity(String id) {
MobileButton mobileButton = this.getById(id);
if(ObjectUtil.isEmpty(mobileButton)) {
throw new CommonException("移动端按钮不存在id值为{}", id);
}
return mobileButton;
}
}

View File

@ -156,7 +156,7 @@ public class MobileMenuServiceImpl extends ServiceImpl<MobileMenuMapper, MobileM
.map(MobileMenu::getId).collect(Collectors.toList())));
if(ObjectUtil.isNotEmpty(toDeleteMenuIdList)) {
// 清除对应的角色与移动端资源信息
sysRelationApi.removeRoleHasMobileMenuRelationByMenuIdList(toDeleteMenuIdList);
sysRelationApi.removeRoleHasMobileMenuRelation(toDeleteMenuIdList);
// 执行删除
this.removeBatchByIds(toDeleteMenuIdList);
}
@ -210,9 +210,11 @@ public class MobileMenuServiceImpl extends ServiceImpl<MobileMenuMapper, MobileM
List<MobileMenu> allModuleAndMenuList = this.list(lambdaQueryWrapper);
List<MobileMenu> mobileModuleList = CollectionUtil.newArrayList();
List<MobileMenu> mobileMenuList = CollectionUtil.newArrayList();
List<MobileMenu> mobileButtonList = CollectionUtil.newArrayList();
allModuleAndMenuList.forEach(mobileMenu -> {
if (mobileMenu.getCategory().equals(MobileResourceCategoryEnum.MODULE.getValue())) mobileModuleList.add(mobileMenu);
if (mobileMenu.getCategory().equals(MobileResourceCategoryEnum.MENU.getValue())) mobileMenuList.add(mobileMenu);
if (mobileMenu.getCategory().equals(MobileResourceCategoryEnum.BUTTON.getValue())) mobileMenuList.add(mobileMenu);
});
List<JSONObject> leafMenuList = CollectionUtil.newArrayList();
MobileMenu rootMobileMenu = new MobileMenu();
@ -243,6 +245,9 @@ public class MobileMenuServiceImpl extends ServiceImpl<MobileMenuMapper, MobileM
} else {
mobileRoleGrantResourceMenuResult.set("parentName", parentJsonObject.getStr("parentName"));
}
mobileRoleGrantResourceMenuResult.set("button", this.getChildListById(mobileButtonList, mobileMenu.getId(), false)
.stream().map(sysMenuItem -> JSONUtil.createObj().set("id", sysMenuItem.getId()).set("title", sysMenuItem.getTitle()))
.collect(Collectors.toList()));
leafMenuList.add(mobileRoleGrantResourceMenuResult);
}
});

View File

@ -115,7 +115,7 @@ public class MobileModuleServiceImpl extends ServiceImpl<MobileModuleMapper, Mob
.map(MobileMenu::getId).collect(Collectors.toList())));
if(ObjectUtil.isNotEmpty(toDeleteMenuIdList)) {
// 清除对应的角色与移动端资源信息
sysRelationApi.removeRoleHasMobileMenuRelationByMenuIdList(toDeleteMenuIdList);
sysRelationApi.removeRoleHasMobileMenuRelation(toDeleteMenuIdList);
// 执行删除
this.removeBatchByIds(toDeleteMenuIdList);
}

View File

@ -12,7 +12,12 @@
*/
package vip.xiaonuo.sys.modular.relation.provider;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;
import vip.xiaonuo.sys.api.SysRelationApi;
import vip.xiaonuo.sys.modular.relation.entity.SysRelation;
@ -20,7 +25,9 @@ import vip.xiaonuo.sys.modular.relation.enums.SysRelationCategoryEnum;
import vip.xiaonuo.sys.modular.relation.service.SysRelationService;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* 关系API接口实现类
@ -41,8 +48,28 @@ public class SysRelationApiProvider implements SysRelationApi {
}
@Override
public void removeRoleHasMobileMenuRelationByMenuIdList(List<String> targetIdList) {
public void removeRoleHasMobileMenuRelation(List<String> targetIdList) {
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().in(SysRelation::getTargetId, targetIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_MOBILE_MENU.getValue()));
}
@Override
public void removeRoleHasMobileButtonRelation(List<String> targetIdList, List<String> buttonIdList) {
sysRelationService.list(new LambdaQueryWrapper<SysRelation>().in(SysRelation::getTargetId, targetIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_MOBILE_MENU.getValue())
.isNotNull(SysRelation::getExtJson)).forEach(mobileRelation -> {
JSONObject extJsonObject = JSONUtil.parseObj(mobileRelation.getExtJson());
List<String> buttonInfoList = extJsonObject.getBeanList("buttonInfo", String.class);
if (ObjectUtil.isNotEmpty(buttonInfoList)) {
Set<String> intersectionDistinct = CollectionUtil.intersectionDistinct(buttonIdList, buttonInfoList);
if(ObjectUtil.isNotEmpty(intersectionDistinct)) {
Collection<String> disjunction = CollectionUtil.disjunction(buttonInfoList, intersectionDistinct);
extJsonObject.set("buttonInfo", disjunction);
}
}
// 清除对应的角色与移动端菜单信息中的授权的移动端按钮信息
sysRelationService.update(new LambdaUpdateWrapper<SysRelation>().eq(SysRelation::getId, mobileRelation.getId())
.set(SysRelation::getExtJson, JSONUtil.toJsonStr(extJsonObject)));
});
}
}

View File

@ -56,5 +56,10 @@ public class SysRoleGrantMobileMenuParam {
@ApiModelProperty(value = "菜单id", position = 1)
@NotBlank(message = "menuId不能为空")
private String menuId;
/** 按钮id集合 */
@ApiModelProperty(value = "按钮id集合", position = 2)
@NotNull(message = "buttonInfo不能为空")
private List<String> buttonInfo;
}
}

View File

@ -40,19 +40,19 @@ public class SysRoleGrantMobileMenuTreeResult {
@ApiModelProperty(value = "模块图标", position = 3)
private String icon;
/** 模块下菜单集合*/
@ApiModelProperty(value = "模块下菜单集合", position = 4)
private List<SysRoleGrantResourceMenuResult> menu;
/** 模块下移动端菜单集合*/
@ApiModelProperty(value = "模块下移动端菜单集合", position = 4)
private List<SysRoleGrantMobileMenuResult> menu;
/**
* 授权菜单类
* 授权移动端菜单类
*
* @author xuyuxiang
* @date 2022/8/13 16:54
*/
@Getter
@Setter
public static class SysRoleGrantResourceMenuResult {
public static class SysRoleGrantMobileMenuResult {
/** 菜单id */
@ApiModelProperty(value = "菜单id", position = 1)
@ -73,5 +73,28 @@ public class SysRoleGrantMobileMenuTreeResult {
/** 模块 */
@ApiModelProperty(value = "菜单模块", position = 5)
private String module;
/** 菜单下按钮集合 */
@ApiModelProperty(value = "菜单下按钮集合", position = 6)
private List<SysRoleGrantMobileButtonResult> button;
/**
* 授权按钮类
*
* @author xuyuxiang
* @date 2022/8/13 16:54
*/
@Getter
@Setter
public static class SysRoleGrantMobileButtonResult {
/** 按钮id */
@ApiModelProperty(value = "按钮id", position = 1)
private String id;
/** 标题 */
@ApiModelProperty(value = "按钮标题", position = 2)
private String title;
}
}
}

View File

@ -49,5 +49,9 @@ public class SysRoleOwnMobileMenuResult {
/** 菜单id */
@ApiModelProperty(value = "菜单id", position = 1)
private String menuId;
/** 按钮id集合 */
@ApiModelProperty(value = "按钮id集合", position = 2)
private List<String> buttonInfo;
}
}

View File

@ -125,6 +125,17 @@ public class SysLoginUserApiProvider implements SaBaseLoginUserApi {
return sysUserService.getButtonCodeList(userId);
}
/**
* 根据用户id获取移动端按钮码集合
*
* @author xuyuxiang
* @date 2022/4/27 22:54
*/
@Override
public List<String> getMobileButtonCodeListListByUserId(String userId) {
return sysUserService.getMobileButtonCodeListListByUserId(userId);
}
/**
* 根据用户id获取权限集合
*

View File

@ -284,6 +284,14 @@ public interface SysUserService extends IService<SysUser> {
**/
List<String> getButtonCodeList(String userId);
/**
* 获取移动端按钮编码集合
*
* @author xuyuxiang
* @date 2022/4/29 11:13
**/
List<String> getMobileButtonCodeListListByUserId(String userId);
/**
* 获取权限集合
*

View File

@ -805,6 +805,25 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return CollectionUtil.newArrayList();
}
@Override
public List<String> getMobileButtonCodeListListByUserId(String userId) {
List<String> roleIdList = sysRelationService.getRelationTargetIdListByObjectIdAndCategory(userId,
SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
if (ObjectUtil.isNotEmpty(roleIdList)) {
List<String> buttonIdList = CollectionUtil.newArrayList();
sysRelationService.getRelationListByObjectIdListAndCategory(roleIdList,
SysRelationCategoryEnum.SYS_ROLE_HAS_MOBILE_MENU.getValue()).forEach(sysRelation -> {
if (ObjectUtil.isNotEmpty(sysRelation.getExtJson())) {
buttonIdList.addAll(JSONUtil.parseObj(sysRelation.getExtJson()).getBeanList("buttonInfo", String.class));
}
});
if (ObjectUtil.isNotEmpty(buttonIdList)) {
return sysButtonService.listByIds(buttonIdList).stream().map(SysButton::getCode).collect(Collectors.toList());
}
}
return CollectionUtil.newArrayList();
}
@Override
public List<JSONObject> getPermissionList(String userId, String orgId) {
if (ObjectUtil.isNotEmpty(orgId)) {