diff --git a/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java b/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java index 7f3b3789..8ffb5a5f 100644 --- a/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java +++ b/buyer-api/src/main/java/cn/lili/controller/passport/MemberBuyerController.java @@ -1,6 +1,12 @@ package cn.lili.controller.passport; +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; +import cn.lili.common.enums.ResultCode; import cn.lili.common.enums.ResultUtil; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.AuthUser; +import cn.lili.common.security.context.UserContext; import cn.lili.common.security.enums.UserEnums; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.member.entity.dos.Member; @@ -35,6 +41,8 @@ public class MemberBuyerController { private SmsUtil smsUtil; @Autowired private VerificationService verificationService; + @Autowired + private Cache cache; @ApiOperation(value = "登录接口") @@ -108,8 +116,11 @@ public class MemberBuyerController { //校验短信验证码是否正确 smsUtil.verifyCode(mobile, VerificationEnums.FIND_USER, uuid, code); //校验是否通过手机号可获取会员,存在则将会员信息存入缓存,有效时间3分钟 - memberService.findByMobile(uuid, mobile); - + Member member = memberService.findByMobile(mobile); + if (member == null) { + throw new ServiceException(ResultCode.USER_NOT_PHONE); + } + cache.put(CachePrefix.FIND_MOBILE + uuid, mobile, 300L); return ResultUtil.success(); } @@ -139,7 +150,11 @@ public class MemberBuyerController { @PutMapping("/modifyPass") public ResultMessage modifyPass(@NotNull(message = "旧密码不能为空") @RequestParam String password, @NotNull(message = "新密码不能为空") @RequestParam String newPassword) { - return ResultUtil.data(memberService.modifyPass(password, newPassword)); + AuthUser tokenUser = UserContext.getCurrentUser(); + if (tokenUser == null) { + throw new ServiceException(ResultCode.USER_NOT_LOGIN); + } + return ResultUtil.data(memberService.modifyPass(tokenUser.getId(), password, newPassword)); } diff --git a/config/application.yml b/config/application.yml index 796fb0ee..5211d997 100644 --- a/config/application.yml +++ b/config/application.yml @@ -69,7 +69,7 @@ spring: default-datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://192.168.0.116:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + url: jdbc:mysql://192.168.0.116:3306/clerk?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai username: root password: lilishop maxActive: 20 diff --git a/framework/src/main/java/cn/lili/cache/CachePrefix.java b/framework/src/main/java/cn/lili/cache/CachePrefix.java index 27740abe..b7eb68bd 100644 --- a/framework/src/main/java/cn/lili/cache/CachePrefix.java +++ b/framework/src/main/java/cn/lili/cache/CachePrefix.java @@ -473,10 +473,18 @@ public enum CachePrefix { * 用户菜单 */ MENU_USER_ID, + /** + * 用户菜单 + */ + STORE_MENU_USER_ID, /** * 用户菜单 */ USER_MENU, + /** + * 用户菜单 + */ + STORE_USER_MENU, /** * 订单暂时缓存 */ diff --git a/framework/src/main/java/cn/lili/common/enums/ResultCode.java b/framework/src/main/java/cn/lili/common/enums/ResultCode.java index 6b621a35..84203990 100644 --- a/framework/src/main/java/cn/lili/common/enums/ResultCode.java +++ b/framework/src/main/java/cn/lili/common/enums/ResultCode.java @@ -133,7 +133,14 @@ public enum ResultCode { USER_CONNECT_BANDING_ERROR(20023, "当前联合登陆方式,已绑定其他账号,需进行解绑操作"), USER_CONNECT_NOT_EXIST_ERROR(20024, "暂无联合登陆信息,无法实现一键注册功能,请点击第三方登录进行授权"), USER_POINTS_ERROR(20024, "用户积分不足"), - + CLERK_SUPPER(20025, "店主无法操作"), + CLERK_SAVE_ERROR(20026, "店员保存失败"), + CLERK_NOT_FOUND_ERROR(20027, "店员不存在"), + USER_STATUS_ERROR(20028, "用户已禁用"), + CLERK_USER_ERROR(20029, "此账户已经绑定其他店铺"), + CLERK_ALREADY_EXIT_ERROR(20030, "店员已经存在"), + CLERK_DISABLED_ERROR(20031, "店员已禁用"), + CLERK_CURRENT_SUPPER(20032, "无法删除当前登录店员"), /** * 权限 */ @@ -142,6 +149,10 @@ public enum ResultCode { PERMISSION_MENU_ROLE_ERROR(21003, "菜单已绑定角色,请先删除或编辑角色"), PERMISSION_DEPARTMENT_DELETE_ERROR(21004, "部门已经绑定管理员,请先删除或编辑管理员"), PERMISSION_BEYOND_TEN(21005, "最多可以设置10个角色"), + PERMISSION_NOT_FOUND_ERROR(21006, "部门不存在"), + PERMISSION_ROLE_NOT_FOUND_ERROR(21007, "角色不存在"), + PERMISSION_CLERK_BAND_ERROR(21008, "此手机号码已绑定其他店铺 "), + /** * 分销 @@ -378,7 +389,7 @@ public enum ResultCode { STORE_NOT_EXIST(50001, "此店铺不存在"), STORE_NAME_EXIST_ERROR(50002, "店铺名称已存在!"), - STORE_APPLY_DOUBLE_ERROR(50003, "已有店铺,无需重复申请!"), + STORE_APPLY_DOUBLE_ERROR(50003, "已经拥有店铺!"), STORE_NOT_OPEN(50004, "该会员未开通店铺"), STORE_NOT_LOGIN_ERROR(50005, "未登录店铺"), STORE_CLOSE_ERROR(50006, "店铺关闭,请联系管理员"), diff --git a/framework/src/main/java/cn/lili/common/exception/GlobalControllerExceptionHandler.java b/framework/src/main/java/cn/lili/common/exception/GlobalControllerExceptionHandler.java index c7ad4bc8..a9715228 100644 --- a/framework/src/main/java/cn/lili/common/exception/GlobalControllerExceptionHandler.java +++ b/framework/src/main/java/cn/lili/common/exception/GlobalControllerExceptionHandler.java @@ -14,10 +14,11 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.validation.ConstraintViolationException; import java.util.List; /** - * 全局异常异常处理 + * 异常处理 * * @author Chopper */ @@ -74,6 +75,15 @@ public class GlobalControllerExceptionHandler { return ResultUtil.error(ResultCode.ERROR.code(), errorMsg); } + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + public ResultMessage constraintExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) { + + log.error("全局异常[RuntimeException]:", e); + + return ResultUtil.error(001, e.getMessage()); + } + @ExceptionHandler(RuntimeException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public ResultMessage runtimeExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) { diff --git a/framework/src/main/java/cn/lili/common/security/AuthUser.java b/framework/src/main/java/cn/lili/common/security/AuthUser.java index 7364421f..b7bc78cb 100644 --- a/framework/src/main/java/cn/lili/common/security/AuthUser.java +++ b/framework/src/main/java/cn/lili/common/security/AuthUser.java @@ -46,6 +46,11 @@ public class AuthUser implements Serializable { * storeId */ private String storeId; + /** + * 如果角色是商家,则存在此店铺id字段 + * clerkId + */ + private String clerkId; /** * 如果角色是商家,则存在此店铺名称字段 @@ -71,5 +76,15 @@ public class AuthUser implements Serializable { this.role = manager; this.isSuper = isSuper; this.nickName = nickName; + this.clerkId = clerkId; + } + + public AuthUser(String username, String id, UserEnums manager, String nickName, Boolean isSuper, String clerkId) { + this.username = username; + this.id = id; + this.role = manager; + this.isSuper = isSuper; + this.nickName = nickName; + this.clerkId = clerkId; } } diff --git a/framework/src/main/java/cn/lili/common/security/token/TokenUtil.java b/framework/src/main/java/cn/lili/common/security/token/TokenUtil.java index 47bd0585..0f92dc6e 100644 --- a/framework/src/main/java/cn/lili/common/security/token/TokenUtil.java +++ b/framework/src/main/java/cn/lili/common/security/token/TokenUtil.java @@ -34,9 +34,9 @@ public class TokenUtil { /** * 构建token * - * @param username 主体 - * @param claim 私有声明 - * @param longTerm 长时间特殊token 如:移动端,微信小程序等 + * @param username 主体 + * @param claim 私有声明 + * @param longTerm 长时间特殊token 如:移动端,微信小程序等 * @param userEnums 用户枚举 * @return TOKEN */ @@ -62,7 +62,7 @@ public class TokenUtil { * 刷新token * * @param oldRefreshToken 刷新token - * @param userEnums 用户枚举 + * @param userEnums 用户枚举 * @return token */ public Token refreshToken(String oldRefreshToken, UserEnums userEnums) { diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/Clerk.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/Clerk.java new file mode 100644 index 00000000..4f900f96 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/Clerk.java @@ -0,0 +1,68 @@ +package cn.lili.modules.member.entity.dos; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.lili.modules.member.entity.dto.ClerkAddDTO; +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 店员Model + * + * @author wget + * @title: Clerk + * @projectName lilishop + * @date 2021/12/28 7:39 下午 + */ +@Data +@TableName("li_clerk") +@ApiModel(value = "店员") +@NoArgsConstructor +public class Clerk extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "店员名称") + private String clerkName; + + @ApiModelProperty(value = "会员ID") + private String memberId; + + @ApiModelProperty(value = "店铺ID") + private String storeId; + + @ApiModelProperty(value = "所属部门id") + private String departmentId; + + @ApiModelProperty(value = "角色id集合") + private String roleIds; + + @ApiModelProperty(value = "是否是店主", hidden = true) + private Boolean shopkeeper = false; + + @ApiModelProperty(value = "是否是超级管理员 超级管理员/普通管理员") + private Boolean isSuper = false; + + @ApiModelProperty(value = "状态 默认true正常 false禁用") + private Boolean status = true; + + + /** + * 构建店员 + * + * @param clerkAddDTO + */ + public Clerk(ClerkAddDTO clerkAddDTO) { + if (!clerkAddDTO.getRoles().isEmpty()) { + this.roleIds = CharSequenceUtil.join(",", clerkAddDTO.getRoles()); + } + this.memberId = clerkAddDTO.getMemberId(); + this.departmentId = clerkAddDTO.getDepartmentId(); + this.storeId = clerkAddDTO.getStoreId(); + this.clerkName = clerkAddDTO.getUsername(); + + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreClerkRole.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreClerkRole.java new file mode 100644 index 00000000..4f658d5d --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreClerkRole.java @@ -0,0 +1,34 @@ +package cn.lili.modules.member.entity.dos; + +import cn.lili.mybatis.BaseIdEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 用户角色 + * + * @author Chopper + * @since 2020/11/19 12:18 + */ +@Data +@TableName("li_clerk_role") +@ApiModel(value = "用户角色") +public class StoreClerkRole extends BaseIdEntity { + + @ApiModelProperty(value = "店员唯一id") + private String clerkId; + + @ApiModelProperty(value = "角色唯一id") + private String roleId; + + public StoreClerkRole(String clerkId, String roleId) { + this.clerkId = clerkId; + this.roleId = roleId; + } + + public StoreClerkRole() { + + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreDepartment.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreDepartment.java new file mode 100644 index 00000000..e2921bbc --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreDepartment.java @@ -0,0 +1,37 @@ +package cn.lili.modules.member.entity.dos; + +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; + + +/** + * 部门 + * + * @author Chopper + * @since 2020/11/19 11:57 + */ +@Data +@TableName("li_store_department") +@ApiModel(value = "店铺部门") +public class StoreDepartment extends BaseEntity { + + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "店铺id", hidden = true) + private String storeId; + + @ApiModelProperty(value = "部门名称") + @NotEmpty(message = "部门名称不能为空") + private String title; + + @ApiModelProperty(value = "父id") + @NotEmpty(message = "父id不能为空") + private String parentId; + + @ApiModelProperty(value = "排序值") + private Double sortOrder; +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreDepartmentRole.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreDepartmentRole.java new file mode 100644 index 00000000..04fb6de6 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreDepartmentRole.java @@ -0,0 +1,34 @@ +package cn.lili.modules.member.entity.dos; + +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 角色部门绑定关系 + * + * @author Chopper + * @since 2020/11/19 12:18 + */ +@Data +@TableName("li_store_department_role") +@ApiModel(value = "店铺角色部门") +@NoArgsConstructor +@AllArgsConstructor +public class StoreDepartmentRole extends BaseEntity { + + + private static final long serialVersionUID = 2342812932116647050L; + + @ApiModelProperty(value = "角色id") + private String roleId; + + @ApiModelProperty(value = "部门id") + private String departmentId; + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreMenu.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreMenu.java new file mode 100644 index 00000000..64522888 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreMenu.java @@ -0,0 +1,48 @@ +package cn.lili.modules.member.entity.dos; + +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 菜单权限 + * + * @author Chopper + * @since 2020/11/19 12:12 + */ +@Data +@TableName("li_store_menu") +@ApiModel(value = "店铺菜单权限") +public class StoreMenu extends BaseEntity { + + private static final long serialVersionUID = 7050744476203495207L; + + + @ApiModelProperty(value = "菜单标题") + private String title; + + @ApiModelProperty(value = "路由名称") + private String name; + + @ApiModelProperty(value = "路径") + private String path; + + @ApiModelProperty(value = "菜单层级") + private Integer level; + + @ApiModelProperty(value = "前端目录文件") + private String frontRoute; + + @ApiModelProperty(value = "父id") + private String parentId = "0"; + + @ApiModelProperty(value = "排序值") + private Double sortOrder; + + @ApiModelProperty(value = "权限URL,*号模糊匹配,逗号分割") + private String permission; + + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreMenuRole.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreMenuRole.java new file mode 100644 index 00000000..0992997f --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreMenuRole.java @@ -0,0 +1,35 @@ +package cn.lili.modules.member.entity.dos; + +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 角色权限绑定关系 + * + * @author Chopper + * @since 2020/11/19 12:18 + */ +@Data +@TableName("li_store_menu_role") +@ApiModel(value = "店铺角色权限") +public class StoreMenuRole extends BaseEntity { + + private static final long serialVersionUID = -4680260092546996026L; + + @ApiModelProperty(value = "角色id") + private String roleId; + + @ApiModelProperty(value = "菜单") + private String menuId; + + @ApiModelProperty(value = "店铺id") + private String storeId; + + @ApiModelProperty(value = "是否拥有操作数据权限,为否则只有查看权限") + private Boolean isSuper; + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreRole.java b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreRole.java new file mode 100644 index 00000000..8057b682 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dos/StoreRole.java @@ -0,0 +1,36 @@ +package cn.lili.modules.member.entity.dos; + +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + + +/** + * 部门 + * + * @author Chopper + * @since 2020/11/19 11:57 + */ +@Data +@TableName("li_store_role") +@ApiModel(value = "店铺角色") +public class StoreRole extends BaseEntity { + + @ApiModelProperty(value = "角色名") + @NotEmpty(message = "角色名称必填") + private String name; + + @ApiModelProperty(value = "店铺id", hidden = true) + private String storeId; + + @ApiModelProperty(value = "是否为注册默认角色") + private Boolean defaultRole = false; + + @ApiModelProperty(value = "备注") + private String description; +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkAddDTO.java b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkAddDTO.java new file mode 100644 index 00000000..6b8207b5 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkAddDTO.java @@ -0,0 +1,64 @@ +package cn.lili.modules.member.entity.dto; + +import cn.lili.common.security.sensitive.Sensitive; +import cn.lili.common.security.sensitive.enums.SensitiveStrategy; +import cn.lili.mybatis.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 店员dto + * + * @author wget + * @title: Clerk + * @projectName lilishop + * @date 2021/12/28 7:39 下午 + */ +@Data +@NoArgsConstructor +public class ClerkAddDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "会员用户名") + @NotEmpty(message = "会员用户名不能为空") + @Length(max = 30, message = "会员用户名不能超过20个字符") + private String username; + + @ApiModelProperty(value = "会员密码") + @NotEmpty(message = "会员密码不能为空") + private String password; + + @NotEmpty(message = "手机号码不能为空") + @ApiModelProperty(value = "手机号码", required = true) + @Sensitive(strategy = SensitiveStrategy.PHONE) + private String mobile; + + @ApiModelProperty(value = "所属部门id") + private String departmentId; + + @ApiModelProperty(value = "是否是超级管理员 超级管理员/普通管理员") + private Boolean isSuper = false; + + @ApiModelProperty(value = "角色") + private List roles; + + @ApiModelProperty(value = "会员id", required = true) + private String memberId; + + @ApiModelProperty(value = "是否是店主", hidden = true) + private Boolean shopkeeper = false; + + @ApiModelProperty(value = "店铺id", hidden = true) + private String storeId; + + +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkEditDTO.java b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkEditDTO.java new file mode 100644 index 00000000..d535103d --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkEditDTO.java @@ -0,0 +1,46 @@ +package cn.lili.modules.member.entity.dto; + +import cn.lili.common.security.sensitive.Sensitive; +import cn.lili.common.security.sensitive.enums.SensitiveStrategy; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 店员dto + * + * @author wget + * @title: Clerk + * @projectName lilishop + * @date 2021/12/28 7:39 下午 + */ +@Data +@NoArgsConstructor +public class ClerkEditDTO { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "店员id", hidden = true) + private String id; + + @ApiModelProperty(value = "会员密码") + private String password; + + @ApiModelProperty(value = "状态") + private Boolean status; + + @ApiModelProperty(value = "所属部门id") + private String departmentId; + + @ApiModelProperty(value = "是否是超级管理员 超级管理员/普通管理员") + private Boolean isSuper = false; + + @ApiModelProperty(value = "角色") + private List roles; + + +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkOperationDTO.java b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkOperationDTO.java new file mode 100644 index 00000000..aa9959e9 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkOperationDTO.java @@ -0,0 +1,48 @@ +package cn.lili.modules.member.entity.dto; + +import cn.lili.mybatis.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +/** + * 管理员入库dto + * + * @author Chopper + * @since 2020/11/16 19:55 + */ +@Data +@ApiModel(value = "店员操作dto") +public class ClerkOperationDTO extends BaseEntity { + + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "用户名") + @Length(max = 20,message = "用户名长度不能超过20个字符") + private String username; + + @ApiModelProperty(value = "密码") + private String password; + + @ApiModelProperty(value = "昵称") + @Length(max = 10,message = "昵称长度不能超过10个字符") + private String nickName; + + @ApiModelProperty(value = "手机") + @Length(max = 11,message = "手机号长度不能超过11") + private String mobile; + + @ApiModelProperty(value = "头像") + private String avatar; + + @ApiModelProperty(value = "描述/详情/备注") + private String description; + + @ApiModelProperty(value = "所属部门id") + private String departmentId; + + @ApiModelProperty(value = "是否为超级管理员") + private Boolean isSuper; +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkQueryDTO.java b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkQueryDTO.java new file mode 100644 index 00000000..956b48f7 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/dto/ClerkQueryDTO.java @@ -0,0 +1,41 @@ +package cn.lili.modules.member.entity.dto; + +import cn.lili.mybatis.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +/** + * 店员查询 + * + * @author Chopper + * @since 2020/11/16 19:55 + */ +@Data +@ApiModel(value = "店员查询") +public class ClerkQueryDTO extends BaseEntity { + + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "店员名称") + @Length(max = 20, message = "用户名长度不能超过20个字符") + private String clerkName; + + @ApiModelProperty(value = "手机") + @Length(max = 11, message = "手机号长度不能超过11") + private String mobile; + + @ApiModelProperty(value = "所属部门id") + private String departmentId; + + @ApiModelProperty(value = "是否为超级管理员") + private Boolean isSuper; + + @ApiModelProperty(value = "状态") + private Boolean status; + + @ApiModelProperty(value = "店铺id", hidden = true) + private String storeId; +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/vo/ClerkVO.java b/framework/src/main/java/cn/lili/modules/member/entity/vo/ClerkVO.java new file mode 100644 index 00000000..ebd6e957 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/vo/ClerkVO.java @@ -0,0 +1,40 @@ +package cn.lili.modules.member.entity.vo; + +import cn.lili.common.utils.BeanUtil; +import cn.lili.modules.member.entity.dos.Clerk; +import cn.lili.modules.member.entity.dos.StoreMenu; +import cn.lili.modules.member.entity.dos.StoreRole; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 管理员VO + * + * @author Chopper + * @since 2020-11-22 09:17 + */ +@Data +public class ClerkVO extends Clerk { + + private static final long serialVersionUID = -2378384199695839312L; + + @ApiModelProperty(value = "手机号") + private String mobile; + + @ApiModelProperty(value = "所属部门名称") + private String departmentTitle; + + @ApiModelProperty(value = "用户拥有角色") + private List roles; + + @ApiModelProperty(value = "用户拥有的权限") + private List menus; + + + public ClerkVO(Clerk clerk) { + BeanUtil.copyProperties(clerk, this); + } + +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreDepartmentVO.java b/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreDepartmentVO.java new file mode 100644 index 00000000..a40ae6a3 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreDepartmentVO.java @@ -0,0 +1,28 @@ +package cn.lili.modules.member.entity.vo; + +import cn.lili.common.utils.BeanUtil; +import cn.lili.modules.member.entity.dos.StoreDepartment; +import cn.lili.modules.permission.entity.dos.Department; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 部门VO + * + * @author Chopper + * @since 2020-11-23 18:48 + */ +@Data +public class StoreDepartmentVO extends StoreDepartment { + + private List children = new ArrayList<>(); + + public StoreDepartmentVO() { + } + + public StoreDepartmentVO(StoreDepartment storeDepartment) { + BeanUtil.copyProperties(storeDepartment, this); + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreMenuVO.java b/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreMenuVO.java new file mode 100644 index 00000000..ae661967 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreMenuVO.java @@ -0,0 +1,45 @@ +package cn.lili.modules.member.entity.vo; + +import cn.lili.common.utils.BeanUtil; +import cn.lili.modules.member.entity.dos.StoreMenu; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * 菜单VO 展示模型 + * + * @author Chopper + * @since 2020/11/20 15:38 + */ + +@Data +public class StoreMenuVO extends StoreMenu { + + @ApiModelProperty(value = "子菜单") + private List children = new ArrayList<>(); + + public StoreMenuVO() { + + } + + public StoreMenuVO(StoreMenu storeMenu) { + BeanUtil.copyProperties(storeMenu, this); + } + + public List getChildren() { + if (children != null) { + children.sort(new Comparator() { + @Override + public int compare(StoreMenuVO o1, StoreMenuVO o2) { + return o1.getSortOrder().compareTo(o2.getSortOrder()); + } + }); + return children; + } + return null; + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreUserMenuVO.java b/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreUserMenuVO.java new file mode 100644 index 00000000..8a6318f2 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/entity/vo/StoreUserMenuVO.java @@ -0,0 +1,29 @@ +package cn.lili.modules.member.entity.vo; + +import cn.lili.modules.member.entity.dos.StoreMenu; +import cn.lili.modules.permission.entity.dos.Menu; +import lombok.Data; + +/** + * RoleMenuVO + * + * @author Chopper + * @since 2020-11-24 11:45 + */ +@Data +public class StoreUserMenuVO extends StoreMenu { + + private static final long serialVersionUID = -7478870595109016162L; + + /** + * 是否是超级管理员 + */ + private Boolean isSuper; + + public Boolean getSuper() { + if (this.isSuper == null) { + return false; + } + return isSuper; + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/ClerkMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/ClerkMapper.java new file mode 100644 index 00000000..ca51b1e6 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/ClerkMapper.java @@ -0,0 +1,34 @@ +package cn.lili.modules.member.mapper; + + +import cn.lili.modules.member.entity.dos.Clerk; +import cn.lili.modules.member.entity.vo.ClerkVO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +/** + * 店员数据处理层 + * + * @author wget + * @title: ClerkMapper + * @projectName lilishop + * @date 2021/12/28 7:39 下午 + */ +public interface ClerkMapper extends BaseMapper { + + /** + * 查询店员分页数据 + * @param page 分页信息 + * @param ew 店铺ID + * @return + */ + @Select("select li_clerk.*,m.id from li_clerk inner join li_member as m on li_clerk.member_id = m.id ${ew.customSqlSegment}") + IPage selectClerkPage(Page page, @Param(Constants.WRAPPER) QueryWrapper ew); + + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/StoreClerkRoleMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/StoreClerkRoleMapper.java new file mode 100644 index 00000000..2b219edc --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/StoreClerkRoleMapper.java @@ -0,0 +1,13 @@ +package cn.lili.modules.member.mapper; + +import cn.lili.modules.member.entity.dos.StoreClerkRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 角色权限数据处理层 + * @author Chopper + * @since 2020-11-22 09:17 + */ +public interface StoreClerkRoleMapper extends BaseMapper { + +} diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/StoreDepartmentMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/StoreDepartmentMapper.java new file mode 100644 index 00000000..252801bf --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/StoreDepartmentMapper.java @@ -0,0 +1,14 @@ +package cn.lili.modules.member.mapper; + +import cn.lili.modules.member.entity.dos.StoreDepartment; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 部门数据处理层 + * + * @author Chopper + * @since 2020-11-22 09:17 + */ +public interface StoreDepartmentMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/StoreDepartmentRoleMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/StoreDepartmentRoleMapper.java new file mode 100644 index 00000000..4171a437 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/StoreDepartmentRoleMapper.java @@ -0,0 +1,14 @@ +package cn.lili.modules.member.mapper; + +import cn.lili.modules.member.entity.dos.StoreDepartmentRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 店铺部门角色数据处理层 + * + * @author Chopper + * @since 2020-11-22 09:17 + */ +public interface StoreDepartmentRoleMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/StoreMenuMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/StoreMenuMapper.java new file mode 100644 index 00000000..3b644df3 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/StoreMenuMapper.java @@ -0,0 +1,44 @@ +package cn.lili.modules.member.mapper; + +import cn.lili.modules.member.entity.dos.StoreMenu; +import cn.lili.modules.member.entity.vo.StoreUserMenuVO; +import cn.lili.modules.permission.entity.dos.Menu; +import cn.lili.modules.permission.entity.vo.UserMenuVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 菜单数据处理层 + * + * @author Chopper + * @since 2020-11-22 09:17 + */ +public interface StoreMenuMapper extends BaseMapper { + + /** + * 根据用户获取菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Select("SELECT menu.* FROM li_store_menu AS menu WHERE menu.id IN (" + + "SELECT rm.menu_id FROM li_store_menu_role AS rm WHERE rm.role_id IN (" + + "SELECT ur.role_id FROM li_clerk_role AS ur WHERE ur.user_id=#{userId}) OR rm.role_id IN (" + + "SELECT dr.role_id FROM li_store_department_role AS dr WHERE dr.id=(" + + "SELECT department_id FROM li_clerk AS au WHERE au.id = #{userId})))") + List findByUserId(String userId); + + /** + * 根据用户获取菜单权限 + * + * @param userId 用户ID + * @return 用户菜单VO列表 + */ + @Select("SELECT rm.is_super as is_super,m.*FROM li_store_menu AS m INNER JOIN li_store_menu_role AS rm ON rm.menu_id=m.id WHERE rm.role_id IN (" + + "SELECT ur.role_id FROM li_clerk_role AS ur WHERE ur.clerk_id=#{userId}) OR rm.role_id IN (" + + "SELECT dr.role_id FROM li_store_department_role AS dr INNER JOIN li_clerk AS au ON au.department_id=dr.department_id " + + "WHERE au.id=#{userId}) GROUP BY m.id,rm.is_super ORDER BY rm.is_super desc") + List getUserRoleMenu(String userId); +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/StoreMenuRoleMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/StoreMenuRoleMapper.java new file mode 100644 index 00000000..be9530b6 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/StoreMenuRoleMapper.java @@ -0,0 +1,14 @@ +package cn.lili.modules.member.mapper; + +import cn.lili.modules.member.entity.dos.StoreMenuRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 角色菜单数据处理层 + * + * @author Chopper + * @since 2020-11-22 09:17 + */ +public interface StoreMenuRoleMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/mapper/StoreRoleMapper.java b/framework/src/main/java/cn/lili/modules/member/mapper/StoreRoleMapper.java new file mode 100644 index 00000000..8f8eb867 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/mapper/StoreRoleMapper.java @@ -0,0 +1,15 @@ +package cn.lili.modules.member.mapper; + +import cn.lili.modules.member.entity.dos.StoreRole; +import cn.lili.modules.permission.entity.dos.Role; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 店铺角色数据处理层 + * + * @author Chopper + * @since 2020-11-22 09:17 + */ +public interface StoreRoleMapper extends BaseMapper { + +} diff --git a/framework/src/main/java/cn/lili/modules/member/service/ClerkService.java b/framework/src/main/java/cn/lili/modules/member/service/ClerkService.java new file mode 100644 index 00000000..17bf036b --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/ClerkService.java @@ -0,0 +1,99 @@ +package cn.lili.modules.member.service; + +import cn.lili.common.vo.PageVO; +import cn.lili.modules.member.entity.dos.Clerk; +import cn.lili.modules.member.entity.dos.Member; +import cn.lili.modules.member.entity.dto.ClerkAddDTO; +import cn.lili.modules.member.entity.dto.ClerkEditDTO; +import cn.lili.modules.member.entity.dto.ClerkQueryDTO; +import cn.lili.modules.member.entity.vo.ClerkVO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 店员业务层 + * + * @author wget + * @title: ClerkService + * @projectName lilishop + * @date 2021/12/28 7:42 下午 + */ +public interface ClerkService extends IService { + + /** + * 店员查询 + * + * @param page + * @param clerkQueryDTO + * @return + */ + IPage clerkForPage(PageVO page, ClerkQueryDTO clerkQueryDTO); + + /** + * 查询店员详细 + * + * @param id 店员id + * @return + */ + ClerkVO get(String id); + + /** + * 修改店员信息 + * + * @param clerkEditDTO 店员 + * @return + */ + Clerk updateClerk(ClerkEditDTO clerkEditDTO); + + /** + * 保存店员 + * + * @param clerkAddDTO 店员 + * @return + */ + Clerk saveClerk(ClerkAddDTO clerkAddDTO); + + /** + * 根据会员id获取店员信息 + * + * @param memberId 会员id + * @return + */ + Clerk getClerkByMemberId(String memberId); + + /** + * 重置店员密码 + * + * @param ids 店员ids + */ + void resetPassword(List ids); + + /** + * 删除店员 + * + * @param ids 店员ids + */ + void deleteClerk(List ids); + + /** + * 检测会员有效性 + * + * @param mobile 手机号码 + * @return + */ + Member checkClerk(String mobile); + + /** + * 店员状态操作 + * + * @param id 店员id + * @param status 状态 + */ + void disable(String id, Boolean status); + + +} diff --git a/framework/src/main/java/cn/lili/modules/member/service/MemberService.java b/framework/src/main/java/cn/lili/modules/member/service/MemberService.java index a4256c17..0fa448a9 100644 --- a/framework/src/main/java/cn/lili/modules/member/service/MemberService.java +++ b/framework/src/main/java/cn/lili/modules/member/service/MemberService.java @@ -35,11 +35,10 @@ public interface MemberService extends IService { /** * 是否可以通过手机获取用户 * - * @param uuid UUID * @param mobile 手机号 * @return 操作状态 */ - boolean findByMobile(String uuid, String mobile); + Member findByMobile(String mobile); /** * 通过用户名获取用户 @@ -86,11 +85,12 @@ public interface MemberService extends IService { /** * 修改用户密码 * + * @param memberId 会员id * @param oldPassword 旧密码 * @param newPassword 新密码 * @return 操作结果 */ - Member modifyPass(String oldPassword, String newPassword); + Member modifyPass(String memberId, String oldPassword, String newPassword); /** * 注册会员 @@ -208,7 +208,7 @@ public interface MemberService extends IService { /** * 获取指定会员数据 * - * @param columns 指定获取的列 + * @param columns 指定获取的列 * @param memberIds 会员ids * @return 指定会员数据 */ @@ -220,4 +220,21 @@ public interface MemberService extends IService { * @param userEnums token角色类型 */ void logout(UserEnums userEnums); + + /** + * 修改会员是否拥有店铺 + * + * @param haveStore 是否拥有店铺 + * @param storeId 店铺id + * @param memberIds 会员id + * @return + */ + void updateHaveShop(Boolean haveStore, String storeId, List memberIds); + + /** + * 重置会员密码为123456 + * + * @param ids 会员id + */ + void resetPassword(List ids); } \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/service/StoreClerkRoleService.java b/framework/src/main/java/cn/lili/modules/member/service/StoreClerkRoleService.java new file mode 100644 index 00000000..58dee8db --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/StoreClerkRoleService.java @@ -0,0 +1,41 @@ +package cn.lili.modules.member.service; + +import cn.lili.modules.member.entity.dos.StoreClerkRole; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 店铺店员角色业务层 + * + * @author Chopper + * @since 2020/11/17 3:46 下午 + */ +public interface StoreClerkRoleService extends IService { + + /** + * 根据用户查看拥有的角色 + * + * @param clerkId 店员id + * @return + */ + List listByUserId(String clerkId); + + /** + * 根据店员id查看角色 + * + * @param clerkId 店员id + * @return + */ + List listId(String clerkId); + + /** + * 更新用户拥有的角色 + * + * @param clerkId 店员id + * @param storeClerkRoles 角色权限 + */ + void updateClerkRole(String clerkId, List storeClerkRoles); + + +} diff --git a/framework/src/main/java/cn/lili/modules/member/service/StoreDepartmentRoleService.java b/framework/src/main/java/cn/lili/modules/member/service/StoreDepartmentRoleService.java new file mode 100644 index 00000000..4ffc9a19 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/StoreDepartmentRoleService.java @@ -0,0 +1,38 @@ +package cn.lili.modules.member.service; + +import cn.lili.modules.member.entity.dos.StoreDepartmentRole; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 部门角色业务层 + * + * @author Chopper + * @since 2020/11/22 12:08 + */ +public interface StoreDepartmentRoleService extends IService { + + /** + * 根据部门获取角色集合 + * + * @param storeDepartmentId 店铺部门id + * @return + */ + List listByDepartmentId(String storeDepartmentId); + + /** + * 更新部门角色关联 + * + * @param storeDepartmentId 店铺部门id + * @param storeDepartmentRoles 店铺部门角色 + */ + void updateByDepartmentId(String storeDepartmentId, List storeDepartmentRoles); + + /** + * 根据部门id删除部门与角色关联 + * + * @param ids id集合 + */ + void deleteByDepartment(List ids); +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/service/StoreDepartmentService.java b/framework/src/main/java/cn/lili/modules/member/service/StoreDepartmentService.java new file mode 100644 index 00000000..43fdd74d --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/StoreDepartmentService.java @@ -0,0 +1,40 @@ +package cn.lili.modules.member.service; + +import cn.lili.modules.member.entity.dos.StoreDepartment; +import cn.lili.modules.member.entity.vo.StoreDepartmentVO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 店铺部门业务层 + * + * @author Chopper + * @since 2020/11/17 3:43 下午 + */ +public interface StoreDepartmentService extends IService { + + /** + * 获取部门树 + * + * @param initWrapper + * @return + */ + List tree(QueryWrapper initWrapper); + + /** + * 删除部门 + * + * @param ids + */ + void deleteByIds(List ids); + + /** + * 更新店铺部门 + * + * @param storeDepartment 店铺部门 + * @return + */ + Boolean update(StoreDepartment storeDepartment); +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/service/StoreMenuRoleService.java b/framework/src/main/java/cn/lili/modules/member/service/StoreMenuRoleService.java new file mode 100644 index 00000000..d179a5b6 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/StoreMenuRoleService.java @@ -0,0 +1,57 @@ +package cn.lili.modules.member.service; + +import cn.lili.modules.member.entity.dos.StoreMenuRole; +import cn.lili.modules.member.entity.vo.StoreUserMenuVO; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 角色菜单接口 + * + * @author Chopper + * @since 2020/11/22 11:43 + */ +public interface StoreMenuRoleService extends IService { + + /** + * 通过角色获取菜单权限列表 + * + * @param roleId + * @return + */ + List findByRoleId(String roleId); + + + /** + * 根据角色集合获取拥有的菜单具体权限 + * + * @param userId + * @return + */ + List findAllMenu(String userId); + + + /** + * 更新某角色拥有到菜单 + * + * @param roleId 角色id + * @param roleMenus + */ + void updateRoleMenu(String roleId, List roleMenus); + + /** + * 根据角色id 删除数据 + * + * @param roleId + */ + void delete(String roleId); + + /** + * 根据角色id 删除数据 + * + * @param roleId + */ + void delete(List roleId); + +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/service/StoreMenuService.java b/framework/src/main/java/cn/lili/modules/member/service/StoreMenuService.java new file mode 100644 index 00000000..934e5600 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/StoreMenuService.java @@ -0,0 +1,74 @@ +package cn.lili.modules.member.service; + +import cn.lili.modules.member.entity.dos.StoreMenu; +import cn.lili.modules.member.entity.vo.StoreMenuVO; +import cn.lili.modules.permission.entity.dto.MenuSearchParams; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.cache.annotation.CacheConfig; + +import java.util.List; + +/** + * 店铺菜单权限业务层 + * + * @author Chopper + * @since 2020/11/17 3:45 下午 + */ +@CacheConfig(cacheNames = "{store_menu}") +public interface StoreMenuService extends IService { + + /** + * 通过用户的菜单权限 + * + * @return + */ + List findUserTree(); + + /** + * 通过用户id获取 + * + * @param userId + * @return + */ + List findUserList(String userId); + + + /** + * 根据角色id获取菜单集合 + * + * @param roleIds + * @return + */ + List findByRoleIds(String roleIds); + + /** + * 树形结构 + * + * @return + */ + List tree(); + + /** + * 查询列表 + * + * @param menuSearchParams + * @return + */ + List searchList(MenuSearchParams menuSearchParams); + + /** + * 批量删除 + * + * @param ids + */ + void deleteIds(List ids); + + /** + * 添加更新菜单 + * + * @param storeMenu 菜单数据 + * @return 是否成功 + */ + boolean saveOrUpdateMenu(StoreMenu storeMenu); + +} diff --git a/framework/src/main/java/cn/lili/modules/member/service/StoreRoleService.java b/framework/src/main/java/cn/lili/modules/member/service/StoreRoleService.java new file mode 100644 index 00000000..74c9804a --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/service/StoreRoleService.java @@ -0,0 +1,56 @@ +package cn.lili.modules.member.service; + + +import cn.lili.modules.member.entity.dos.StoreRole; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 角色业务层 + * + * @author Chopper + * @since 2020/11/17 3:45 下午 + */ +public interface StoreRoleService extends IService { + + /** + * 获取默认角色 + * + * @param defaultRole + * @return + */ + List findByDefaultRole(Boolean defaultRole); + + + /** + * 批量删除角色 + * + * @param roleIds + */ + void deleteRoles(List roleIds); + + /** + * 修改角色 + * + * @param storeRole 店铺角色 + * @return + */ + Boolean update(StoreRole storeRole); + + /** + * 保存店铺角色 + * + * @param storeRole 店铺角色 + * @return + */ + Boolean saveStoreRole(StoreRole storeRole); + + /** + * 当前店铺 根据角色id查询角色 + * + * @param ids 角色id + * @return + */ + List list(List ids); +} diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/ClerkServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/ClerkServiceImpl.java new file mode 100644 index 00000000..9edc97fd --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/ClerkServiceImpl.java @@ -0,0 +1,320 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.lili.common.enums.ResultCode; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.context.UserContext; +import cn.lili.common.utils.BeanUtil; +import cn.lili.common.utils.StringUtils; +import cn.lili.common.vo.PageVO; +import cn.lili.modules.member.entity.dos.Clerk; +import cn.lili.modules.member.entity.dos.Member; +import cn.lili.modules.member.entity.dos.StoreRole; +import cn.lili.modules.member.entity.dto.ClerkAddDTO; +import cn.lili.modules.member.entity.dto.ClerkEditDTO; +import cn.lili.modules.member.entity.dto.ClerkQueryDTO; +import cn.lili.modules.member.entity.vo.ClerkVO; +import cn.lili.modules.member.mapper.ClerkMapper; +import cn.lili.modules.member.service.ClerkService; +import cn.lili.modules.member.service.MemberService; +import cn.lili.modules.member.service.StoreDepartmentService; +import cn.lili.modules.member.service.StoreRoleService; +import cn.lili.mybatis.util.PageUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 店员业务实现 + * + * @author wget + * @title: ClerkServiceImpl + * @projectName lilishop + * @date 2021/12/28 8:13 下午 + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class ClerkServiceImpl extends ServiceImpl implements ClerkService { + + @Autowired + private StoreRoleService storeRoleService; + @Autowired + private StoreDepartmentService storeDepartmentService; + @Autowired + private MemberService memberService; + @Autowired + private ClerkMapper clerkMapper; + + @Override + public IPage clerkForPage(PageVO page, ClerkQueryDTO clerkQueryDTO) { + + QueryWrapper clerkVOQueryWrapper = new QueryWrapper<>(); + clerkVOQueryWrapper.eq("li_clerk.store_id", UserContext.getCurrentUser().getStoreId()); + clerkVOQueryWrapper.eq(StringUtils.isNotEmpty(clerkQueryDTO.getDepartmentId()), "li_clerk.department_id", clerkQueryDTO.getDepartmentId()); + clerkVOQueryWrapper.like(StringUtils.isNotEmpty(clerkQueryDTO.getClerkName()), "li_clerk.clerk_name", clerkQueryDTO.getClerkName()); + clerkVOQueryWrapper.like(StringUtils.isNotEmpty(clerkQueryDTO.getMobile()), "m.mobile", clerkQueryDTO.getMobile()); + IPage clerkPage = this.clerkMapper.selectClerkPage(PageUtil.initPage(page), clerkVOQueryWrapper); + + List result = new ArrayList<>(); + clerkPage.getRecords().forEach(clerk -> { + ClerkVO clerkVO = new ClerkVO(clerk); + result.add(clerkVO); + }); + + Page pageResult = new Page(clerkPage.getCurrent(), clerkPage.getSize(), clerkPage.getTotal()); + pageResult.setRecords(result); + return pageResult; + + + /*Page clerkPage = page(initPage, initWrapper); + + if (clerkPage.getRecords().size() > 0) { + List roles = storeRoleService.list(new QueryWrapper() + .eq("store_id", UserContext.getCurrentUser().getStoreId())); + + List departments = storeDepartmentService.list(new QueryWrapper() + .eq("store_id", UserContext.getCurrentUser().getStoreId())); + + List memberIds = new ArrayList<>(); + clerkPage.getRecords().forEach(clerk -> { + memberIds.add(clerk.getMemberId()); + }); + List members = memberService.list(new QueryWrapper().in("id", memberIds)); + + List result = new ArrayList<>(); + + clerkPage.getRecords().forEach(clerk -> { + ClerkVO clerkVO = new ClerkVO(clerk); + if (!CharSequenceUtil.isEmpty(clerk.getDepartmentId())) { + try { + clerkVO.setDepartmentTitle( + departments.stream().filter + (department -> department.getId().equals(clerk.getDepartmentId())) + .collect(Collectors.toList()) + .get(0) + .getTitle() + ); + } catch (Exception e) { + log.error("填充部门信息异常", e); + } + } + clerkVO.setMobile( + members.stream().filter + (member -> member.getId().equals(clerk.getMemberId())) + .collect(Collectors.toList()) + .get(0) + .getMobile() + ); + if (!StringUtils.isEmpty(clerk.getRoleIds())) { + try { + List memberRoles = Arrays.asList(clerk.getRoleIds().split(",")); + clerkVO.setRoles( + roles.stream().filter + (role -> memberRoles.contains(role.getId())) + .collect(Collectors.toList()) + ); + } catch (Exception e) { + log.error("填充部门信息异常", e); + } + } + result.add(clerkVO); + }); + Page pageResult = new Page(clerkPage.getCurrent(), clerkPage.getSize(), clerkPage.getTotal()); + pageResult.setRecords(result); + return pageResult; + } + return new Page();*/ + } + + + @Override + public ClerkVO get(String id) { + Clerk clerk = this.getById(id); + ClerkVO clerkVO = new ClerkVO(clerk); + //手机号码 + clerkVO.setMobile(memberService.getById(clerk.getMemberId()).getMobile()); + if (!CharSequenceUtil.isEmpty(clerk.getDepartmentId())) { + clerkVO.setDepartmentTitle(storeDepartmentService.getById(clerk.getDepartmentId()).getTitle()); + } + if (!StringUtils.isEmpty(clerk.getRoleIds())) { + List memberRoles = Arrays.asList(clerk.getRoleIds().split(",")); + List roles = storeRoleService.list(new QueryWrapper() + .eq("store_id", UserContext.getCurrentUser().getStoreId())); + clerkVO.setRoles( + roles.stream().filter + (role -> memberRoles.contains(role.getId())) + .collect(Collectors.toList()) + ); + } + return clerkVO; + } + + @Override + public Clerk updateClerk(ClerkEditDTO clerkEditDTO) { + Clerk clerk = this.getById(clerkEditDTO.getId()); + if (clerk != null) { + //校验当前店员是否是当前店铺的 + if (!clerk.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + if(clerkEditDTO.getIsSuper()){ + clerk.setRoleIds(""); + }else{ + //角色赋值 + if (!clerkEditDTO.getRoles().isEmpty()) { + clerk.setRoleIds(CharSequenceUtil.join(",", clerkEditDTO.getRoles())); + } + } + + //部门校验 + if (StringUtils.isNotEmpty(clerkEditDTO.getDepartmentId())) { + if (storeDepartmentService.getById(clerkEditDTO.getDepartmentId()) != null) { + clerk.setDepartmentId(clerkEditDTO.getDepartmentId()); + } else { + throw new ServiceException(ResultCode.PERMISSION_NOT_FOUND_ERROR); + } + } + clerk.setIsSuper(clerkEditDTO.getIsSuper()); + this.updateById(clerk); + return clerk; + } + throw new ServiceException(ResultCode.CLERK_NOT_FOUND_ERROR); + } + + @Override + public Clerk saveClerk(ClerkAddDTO clerkAddDTO) { + Clerk clerk = new Clerk(clerkAddDTO); + clerk.setShopkeeper(clerkAddDTO.getShopkeeper()); + clerk.setIsSuper(clerkAddDTO.getIsSuper()); + //校验此会员是否已经是店员 + Clerk temp = this.getClerkByMemberId(clerkAddDTO.getMemberId()); + if (temp != null && !temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.CLERK_USER_ERROR); + } + if (temp != null && temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.CLERK_ALREADY_EXIT_ERROR); + } + //部门校验 + if (StringUtils.isNotEmpty(clerkAddDTO.getDepartmentId())) { + if (storeDepartmentService.getById(clerkAddDTO.getDepartmentId()) == null) { + throw new ServiceException(ResultCode.PERMISSION_NOT_FOUND_ERROR); + } + } + //角色校验 + if (clerkAddDTO.getRoles() != null && clerkAddDTO.getRoles().size() > 0) { + List storeRoles = storeRoleService.list(clerkAddDTO.getRoles()); + if (storeRoles.size() != clerkAddDTO.getRoles().size()) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + } + this.save(clerk); + return clerk; + } + + @Override + public Clerk getClerkByMemberId(String memberId) { + return this.getOne(new QueryWrapper().eq("member_id", memberId)); + } + + @Override + public void resetPassword(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId()); + queryWrapper.in("id", ids); + List clerks = this.clerkMapper.selectList(queryWrapper); + //校验要重置的店员是否是当前店铺的店员 + if (clerks.size() != ids.size()) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + //店员密码就是会员密码所以要组织会员修改密码参数信息 + List memberIds = new ArrayList<>(); + clerks.forEach(clerk -> { + //如果是店主无法重置密码 + if (clerk.getShopkeeper()) { + throw new ServiceException(ResultCode.CLERK_SUPPER); + } + memberIds.add(clerk.getMemberId()); + }); + memberService.resetPassword(memberIds); + } + + + @Override + public void deleteClerk(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId()); + queryWrapper.in("id", ids); + List clerks = this.clerkMapper.selectList(queryWrapper); + if (clerks.size() > 0) { + //校验要重置的店员是否是当前店铺的店员 + if (clerks.size() != ids.size()) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + //删除店员 + this.removeByIds(ids); + //更改会员为为拥有店铺 + List memberIds = new ArrayList<>(); + clerks.forEach(clerk -> { + //无法删除当前登录的店员 + if (UserContext.getCurrentUser().getClerkId().equals(clerk.getId())) { + throw new ServiceException(ResultCode.CLERK_CURRENT_SUPPER); + } + //无法删除店主 + if (clerk.getShopkeeper()) { + throw new ServiceException(ResultCode.CLERK_SUPPER); + } + memberIds.add(clerk.getMemberId()); + }); + memberService.updateHaveShop(false, null, memberIds); + } + } + + @Override + public Member checkClerk(String mobile) { + //校验是否已经是会员 + Member member = memberService.findByMobile(mobile); + if (member != null) { + //校验要添加的会员是否已经是店主 + if (member.getHaveStore()) { + throw new ServiceException(ResultCode.STORE_APPLY_DOUBLE_ERROR); + } + //校验会员的有效性 + if (!member.getDisabled()) { + throw new ServiceException(ResultCode.USER_STATUS_ERROR); + } + //校验此会员是否已经是店员 + Clerk clerk = this.getClerkByMemberId(member.getId()); + if (clerk != null && !clerk.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.CLERK_USER_ERROR); + } + if (clerk != null && clerk.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.CLERK_ALREADY_EXIT_ERROR); + } + return member; + } + return new Member(); + } + + @Override + public void disable(String id, Boolean status) { + Clerk clerk = this.getById(id); + if (clerk == null) { + throw new ServiceException(ResultCode.USER_NOT_EXIST); + } + //店主无法禁用 + if (clerk.getShopkeeper() && clerk.getStatus()) { + throw new ServiceException(ResultCode.CLERK_SUPPER); + } + clerk.setStatus(status); + this.updateById(clerk); + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java index 1695271e..ccf6908f 100644 --- a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java @@ -17,6 +17,7 @@ import cn.lili.common.security.token.Token; import cn.lili.common.sensitive.SensitiveWordsFilter; import cn.lili.common.utils.BeanUtil; import cn.lili.common.utils.CookieUtil; +import cn.lili.common.utils.StringUtils; import cn.lili.common.utils.UuidUtils; import cn.lili.common.vo.PageVO; import cn.lili.modules.connect.config.ConnectAuthEnum; @@ -119,16 +120,10 @@ public class MemberServiceImpl extends ServiceImpl impleme } @Override - public boolean findByMobile(String uuid, String mobile) { + public Member findByMobile(String mobile) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("mobile", mobile); - Member member = this.baseMapper.selectOne(queryWrapper); - if (member == null) { - throw new ServiceException(ResultCode.USER_NOT_PHONE); - } - cache.put(CachePrefix.FIND_MOBILE + uuid, mobile, 300L); - - return true; + return this.baseMapper.selectOne(queryWrapper); } @Override @@ -256,12 +251,8 @@ public class MemberServiceImpl extends ServiceImpl impleme } @Override - public Member modifyPass(String oldPassword, String newPassword) { - AuthUser tokenUser = UserContext.getCurrentUser(); - if (tokenUser == null) { - throw new ServiceException(ResultCode.USER_NOT_LOGIN); - } - Member member = this.getById(tokenUser.getId()); + public Member modifyPass(String memberId, String oldPassword, String newPassword) { + Member member = this.getById(memberId); //判断旧密码输入是否正确 if (!new BCryptPasswordEncoder().matches(oldPassword, member.getPassword())) { throw new ServiceException(ResultCode.USER_OLD_PASSWORD_ERROR); @@ -581,6 +572,31 @@ public class MemberServiceImpl extends ServiceImpl impleme } } + @Override + public void updateHaveShop(Boolean haveStore, String storeId, List memberIds) { + List members = this.baseMapper.selectBatchIds(memberIds); + if (members.size() > 0) { + members.forEach(member -> { + member.setHaveStore(haveStore); + if (haveStore) { + member.setStoreId(storeId); + } else { + member.setStoreId(null); + } + }); + this.updateBatchById(members); + } + } + + @Override + public void resetPassword(List ids) { + String password = new BCryptPasswordEncoder().encode(StringUtils.md5("123456")); + LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); + lambdaUpdateWrapper.in(Member::getId, ids); + lambdaUpdateWrapper.set(Member::getPassword, password); + this.update(lambdaUpdateWrapper); + } + /** * 检测会员 * @@ -597,4 +613,5 @@ public class MemberServiceImpl extends ServiceImpl impleme throw new ServiceException(ResultCode.USER_PHONE_EXIST); } } + } \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreClerkRoleServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreClerkRoleServiceImpl.java new file mode 100644 index 00000000..a37b6f7a --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreClerkRoleServiceImpl.java @@ -0,0 +1,52 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.lili.modules.member.entity.dos.StoreClerkRole; +import cn.lili.modules.member.mapper.StoreClerkRoleMapper; +import cn.lili.modules.member.service.StoreClerkRoleService; +import cn.lili.modules.permission.entity.dos.UserRole; +import cn.lili.modules.permission.mapper.UserRoleMapper; +import cn.lili.modules.permission.service.UserRoleService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用户权限业务层实现 + * + * @author Chopper + * @since 2020/11/17 3:52 下午 + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class StoreClerkRoleServiceImpl extends ServiceImpl implements StoreClerkRoleService { + + @Override + public List listByUserId(String clerkId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("clerk_id", clerkId); + return this.baseMapper.selectList(queryWrapper); + } + + @Override + public List listId(String clerkId) { + List userRoleList = this.listByUserId(clerkId); + List strings = new ArrayList<>(); + userRoleList.forEach(item -> strings.add(item.getRoleId())); + return strings; + } + + @Override + public void updateClerkRole(String clerkId, List storeClerkRoles) { + //删除 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("clerk_id", clerkId); + this.remove(queryWrapper); + //保存 + this.saveBatch(storeClerkRoles); + } + +} diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreDepartmentRoleServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreDepartmentRoleServiceImpl.java new file mode 100644 index 00000000..17dc7de0 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreDepartmentRoleServiceImpl.java @@ -0,0 +1,49 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.lili.common.security.context.UserContext; +import cn.lili.modules.member.entity.dos.StoreDepartmentRole; +import cn.lili.modules.member.mapper.StoreDepartmentRoleMapper; +import cn.lili.modules.member.service.StoreDepartmentRoleService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 部门角色业务层实现 + * + * @author Chopper + * @since 2020/11/22 12:08 + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class StoreDepartmentRoleServiceImpl extends ServiceImpl implements StoreDepartmentRoleService { + + + @Override + public List listByDepartmentId(String storeDepartmentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("department_id", storeDepartmentId); + return this.baseMapper.selectList(queryWrapper); + } + + @Override + public void updateByDepartmentId(String storeDepartmentId, List storeDepartmentRoles) { + if (storeDepartmentRoles.size() > 0) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("department_id", storeDepartmentId); + this.remove(queryWrapper); + this.saveBatch(storeDepartmentRoles); + } + } + + @Override + public void deleteByDepartment(List ids) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("department_id", ids); + this.remove(queryWrapper); + } +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreDepartmentServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreDepartmentServiceImpl.java new file mode 100644 index 00000000..f9a2c1df --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreDepartmentServiceImpl.java @@ -0,0 +1,112 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.lili.common.enums.ResultCode; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.context.UserContext; +import cn.lili.modules.member.entity.dos.Clerk; +import cn.lili.modules.member.entity.dos.StoreDepartment; +import cn.lili.modules.member.entity.vo.StoreDepartmentVO; +import cn.lili.modules.member.mapper.StoreDepartmentMapper; +import cn.lili.modules.member.service.ClerkService; +import cn.lili.modules.member.service.StoreDepartmentRoleService; +import cn.lili.modules.member.service.StoreDepartmentService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * 店铺部门业务层实现 + * + * @author Chopper + * @since 2020/11/17 3:47 下午 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class StoreDepartmentServiceImpl extends ServiceImpl implements StoreDepartmentService { + + @Autowired + private StoreDepartmentRoleService storeDepartmentRoleService; + + @Autowired + private ClerkService clerkService; + + @Override + public void deleteByIds(List ids) { + //校验是否有操作店铺部门权限 + List storeDepartments = this.list(new QueryWrapper() + .in("id", ids) + .eq("store_id", UserContext.getCurrentUser().getStoreId())); + if (storeDepartments.size() != ids.size()) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + //校验店员是否绑定部门 + if (clerkService.count(new QueryWrapper().in("department_id", ids)) > 0) { + throw new ServiceException(ResultCode.PERMISSION_DEPARTMENT_DELETE_ERROR); + } + //删除店铺部门 + this.removeByIds(ids); + //删除店铺部门角色 + storeDepartmentRoleService.deleteByDepartment(ids); + } + + @Override + public List tree(QueryWrapper initWrapper) { + try { + List departments = this.list(initWrapper); + + List all = new ArrayList<>(); + departments.forEach(item -> all.add(new StoreDepartmentVO(item))); + + List tree = new ArrayList<>(); + all.forEach(item -> { + if ("0".equals(item.getParentId())) { + initChild(item, all); + tree.add(item); + } + }); + + return tree; + } catch (Exception e) { + log.error("部门业务错误", e); + return null; + } + } + + + /** + * 递归初始化子树 + * + * @param tree 树结构 + * @param departmentVOS 数据库对象集合 + */ + private void initChild(StoreDepartmentVO tree, List departmentVOS) { + departmentVOS.stream() + .filter(item -> (item.getParentId().equals(tree.getId()))) + .forEach(child -> { + StoreDepartmentVO childTree = new StoreDepartmentVO(child); + initChild(childTree, departmentVOS); + tree.getChildren().add(childTree); + }); + } + + @Override + public Boolean update(StoreDepartment storeDepartment) { + StoreDepartment temp = this.getById(storeDepartment); + //校验部门是否存在 + if (temp == null) { + throw new ServiceException(ResultCode.PERMISSION_NOT_FOUND_ERROR); + } + //校验店铺权限 + if (!temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + return this.updateById(storeDepartment); + } +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreMenuRoleServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreMenuRoleServiceImpl.java new file mode 100644 index 00000000..5b876517 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreMenuRoleServiceImpl.java @@ -0,0 +1,104 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; +import cn.lili.common.security.context.UserContext; +import cn.lili.modules.member.entity.dos.StoreMenuRole; +import cn.lili.modules.member.entity.vo.StoreUserMenuVO; +import cn.lili.modules.member.mapper.StoreMenuMapper; +import cn.lili.modules.member.mapper.StoreMenuRoleMapper; +import cn.lili.modules.member.service.StoreMenuRoleService; +import cn.lili.modules.permission.entity.dos.RoleMenu; +import cn.lili.modules.permission.entity.vo.UserMenuVO; +import cn.lili.modules.permission.mapper.MenuMapper; +import cn.lili.modules.permission.mapper.RoleMenuMapper; +import cn.lili.modules.permission.service.RoleMenuService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import groovy.util.logging.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 角色菜单业务层实现 + * + * @author Chopper + * @since 2020/11/22 11:43 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class StoreMenuRoleServiceImpl extends ServiceImpl implements StoreMenuRoleService { + + /** + * 菜单 + */ + @Resource + private StoreMenuMapper storeMenuMapper; + + + @Autowired + private Cache cache; + + @Override + public List findByRoleId(String roleId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StoreMenuRole::getRoleId, roleId); + return this.baseMapper.selectList(queryWrapper); + } + + @Override + public List findAllMenu(String userId) { + String cacheKey = CachePrefix.STORE_USER_MENU.getPrefix() + userId; + List menuList = (List) cache.get(cacheKey); + if (menuList == null) { + menuList = storeMenuMapper.getUserRoleMenu(userId); + cache.put(cacheKey, menuList); + } + return menuList; + } + + + @Override + public void updateRoleMenu(String roleId, List roleMenus) { + try { + roleMenus.forEach(role -> { + role.setStoreId(UserContext.getCurrentUser().getStoreId()); + }); + //删除角色已经绑定的菜单 + this.delete(roleId); + //重新保存角色菜单关系 + this.saveBatch(roleMenus); + + cache.vagueDel(CachePrefix.MENU_USER_ID.getPrefix()); + cache.vagueDel(CachePrefix.USER_MENU.getPrefix()); + } catch (Exception e) { + log.error("修改用户权限错误", e); + } + } + + @Override + public void delete(String roleId) { + //删除 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("role_id", roleId); + this.remove(queryWrapper); + cache.vagueDel(CachePrefix.STORE_MENU_USER_ID.getPrefix()); + cache.vagueDel(CachePrefix.STORE_USER_MENU.getPrefix()); + } + + @Override + public void delete(List roleId) { + //删除 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("role_id", roleId); + this.remove(queryWrapper); + cache.vagueDel(CachePrefix.STORE_MENU_USER_ID.getPrefix()); + cache.vagueDel(CachePrefix.STORE_USER_MENU.getPrefix()); + } +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreMenuServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreMenuServiceImpl.java new file mode 100644 index 00000000..ef757344 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreMenuServiceImpl.java @@ -0,0 +1,166 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; +import cn.lili.common.enums.ResultCode; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.AuthUser; +import cn.lili.common.security.context.UserContext; +import cn.lili.common.vo.SearchVO; +import cn.lili.modules.member.entity.dos.StoreMenu; +import cn.lili.modules.member.entity.dos.StoreMenuRole; +import cn.lili.modules.member.entity.vo.StoreMenuVO; +import cn.lili.modules.member.mapper.StoreMenuMapper; +import cn.lili.modules.member.service.StoreMenuRoleService; +import cn.lili.modules.member.service.StoreMenuService; +import cn.lili.modules.permission.entity.dto.MenuSearchParams; +import cn.lili.mybatis.util.PageUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * 权限业务层实现 + * + * @author Chopper + * @since 2020/11/17 3:49 下午 + */ +@Slf4j +@Service +public class StoreMenuServiceImpl extends ServiceImpl implements StoreMenuService { + /** + * 菜单角色 + */ + @Autowired + private StoreMenuRoleService storeMenuRoleService; + + @Autowired + private Cache> cache; + + @Override + public void deleteIds(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("menu_id", ids); + //如果已有角色绑定菜单,则不能直接删除 + if (storeMenuRoleService.count(queryWrapper) > 0) { + throw new ServiceException(ResultCode.PERMISSION_MENU_ROLE_ERROR); + } + this.removeByIds(ids); + } + + + @Override + public List findUserTree() { + AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser()); + if (Boolean.TRUE.equals(authUser.getIsSuper())) { + return this.tree(); + } + List userMenus = this.baseMapper.findByUserId(authUser.getId()); + return this.tree(userMenus); + } + + @Override + public List findUserList(String userId) { + String cacheKey = CachePrefix.STORE_MENU_USER_ID.getPrefix() + userId; + List menuList = cache.get(cacheKey); + if (menuList == null) { + menuList = this.baseMapper.findByUserId(userId); + cache.put(cacheKey, menuList); + } + return menuList; + } + + /** + * 添加更新菜单 + * + * @param storeMenu 菜单数据 + * @return 是否成功 + */ + @Override + public boolean saveOrUpdateMenu(StoreMenu storeMenu) { + if (CharSequenceUtil.isNotEmpty(storeMenu.getId())) { + cache.vagueDel(CachePrefix.STORE_MENU_USER_ID.getPrefix()); + } + return this.saveOrUpdate(storeMenu); + } + + @Override + public List findByRoleIds(String roleId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("role_id", roleId); + return this.list(queryWrapper); + } + + @Override + public List searchList(MenuSearchParams menuSearchParams) { + //title 需要特殊处理 + String title = null; + if (CharSequenceUtil.isNotEmpty(menuSearchParams.getTitle())) { + title = menuSearchParams.getTitle(); + menuSearchParams.setTitle(null); + } + QueryWrapper queryWrapper = PageUtil.initWrapper(menuSearchParams, new SearchVO()); + if (CharSequenceUtil.isNotEmpty(title)) { + queryWrapper.like("title", title); + } + queryWrapper.orderByDesc("sort_order"); + return this.baseMapper.selectList(queryWrapper); + } + + + @Override + public List tree() { + try { + List menus = this.list(); + return tree(menus); + } catch (Exception e) { + log.error("菜单树错误", e); + } + return Collections.emptyList(); + } + + /** + * 传入自定义菜单集合 + * + * @param menus 自定义菜单集合 + * @return 修改后的自定义菜单集合 + */ + private List tree(List menus) { + List tree = new ArrayList<>(); + menus.forEach(item -> { + if (item.getLevel() == 0) { + StoreMenuVO treeItem = new StoreMenuVO(item); + initChild(treeItem, menus); + tree.add(treeItem); + } + }); + //对一级菜单排序 + tree.sort(Comparator.comparing(StoreMenu::getSortOrder)); + return tree; + } + + /** + * 递归初始化子树 + * + * @param tree 树结构 + * @param menus 数据库对象集合 + */ + private void initChild(StoreMenuVO tree, List menus) { + if (menus == null) { + return; + } + menus.stream() + .filter(item -> (item.getParentId().equals(tree.getId()))) + .forEach(child -> { + StoreMenuVO childTree = new StoreMenuVO(child); + initChild(childTree, menus); + tree.getChildren().add(childTree); + }); + } + +} diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreRoleServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreRoleServiceImpl.java new file mode 100644 index 00000000..af2e7a47 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/StoreRoleServiceImpl.java @@ -0,0 +1,106 @@ +package cn.lili.modules.member.serviceimpl; + +import cn.lili.common.enums.ResultCode; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.context.UserContext; +import cn.lili.modules.member.entity.dos.StoreRole; +import cn.lili.modules.member.mapper.StoreRoleMapper; +import cn.lili.modules.member.service.StoreClerkRoleService; +import cn.lili.modules.member.service.StoreDepartmentRoleService; +import cn.lili.modules.member.service.StoreMenuRoleService; +import cn.lili.modules.member.service.StoreRoleService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色业务层实现 + * + * @author Chopper + * @since 2020/11/17 3:50 下午 + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class StoreRoleServiceImpl extends ServiceImpl implements StoreRoleService { + + /** + * 部门角色 + */ + @Autowired + private StoreDepartmentRoleService storeDepartmentRoleService; + /** + * 用户权限 + */ + @Autowired + private StoreClerkRoleService storeClerkRoleService; + + @Autowired + private StoreMenuRoleService storeMenuRoleService; + + @Override + public List findByDefaultRole(Boolean defaultRole) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("default_role", true); + return baseMapper.selectList(queryWrapper); + } + + @Override + public void deleteRoles(List roleIds) { + //校验是否为当前店铺 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("id", roleIds); + List roles = this.baseMapper.selectList(queryWrapper); + roles.forEach(role -> { + if (!role.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR); + } + }); + queryWrapper = new QueryWrapper<>(); + queryWrapper.in("role_id", roleIds); + //校验是否绑定店铺部门 + if (storeDepartmentRoleService.count(queryWrapper) > 0) { + throw new ServiceException(ResultCode.PERMISSION_DEPARTMENT_ROLE_ERROR); + } + //校验是否绑定店员 + if (storeClerkRoleService.count(queryWrapper) > 0) { + throw new ServiceException(ResultCode.PERMISSION_USER_ROLE_ERROR); + } + //删除角色 + this.removeByIds(roleIds); + //删除角色与菜单关联 + storeMenuRoleService.remove(queryWrapper); + } + + @Override + public Boolean update(StoreRole storeRole) { + StoreRole storeRoleTemp = this.getById(storeRole.getId()); + //校验店铺角色是否存在 + if (storeRoleTemp == null) { + throw new ServiceException(ResultCode.PERMISSION_ROLE_NOT_FOUND_ERROR); + } + //校验店铺角色是否属于当前店铺 + if (!storeRoleTemp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) { + throw new ServiceException(ResultCode.PERMISSION_ROLE_NOT_FOUND_ERROR); + } + return updateById(storeRole); + } + + + @Override + public Boolean saveStoreRole(StoreRole storeRole) { + storeRole.setStoreId(UserContext.getCurrentUser().getStoreId()); + return save(storeRole); + } + + @Override + public List list(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId()); + queryWrapper.in("id", ids); + return this.baseMapper.selectList(queryWrapper); + } +} diff --git a/framework/src/main/java/cn/lili/modules/member/token/StoreTokenGenerate.java b/framework/src/main/java/cn/lili/modules/member/token/StoreTokenGenerate.java index 9d10db60..a6040a51 100644 --- a/framework/src/main/java/cn/lili/modules/member/token/StoreTokenGenerate.java +++ b/framework/src/main/java/cn/lili/modules/member/token/StoreTokenGenerate.java @@ -1,20 +1,34 @@ package cn.lili.modules.member.token; +import cn.hutool.core.text.CharSequenceUtil; +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; import cn.lili.common.enums.ResultCode; import cn.lili.common.exception.ServiceException; import cn.lili.common.security.AuthUser; +import cn.lili.common.security.enums.PermissionEnum; import cn.lili.common.security.enums.UserEnums; import cn.lili.common.security.token.Token; import cn.lili.common.security.token.TokenUtil; import cn.lili.common.security.token.base.AbstractTokenGenerate; +import cn.lili.modules.member.entity.dos.Clerk; import cn.lili.modules.member.entity.dos.Member; +import cn.lili.modules.member.entity.vo.StoreUserMenuVO; +import cn.lili.modules.member.service.ClerkService; import cn.lili.modules.member.service.MemberService; +import cn.lili.modules.member.service.StoreMenuRoleService; +import cn.lili.modules.permission.entity.vo.UserMenuVO; import cn.lili.modules.store.entity.dos.Store; import cn.lili.modules.store.service.StoreService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * 商家token生成 * @@ -30,6 +44,12 @@ public class StoreTokenGenerate extends AbstractTokenGenerate { private StoreService storeService; @Autowired private TokenUtil tokenUtil; + @Autowired + private StoreMenuRoleService storeMenuRoleService; + @Autowired + private Cache cache; + @Autowired + private ClerkService clerkService; @Override public Token createToken(String username, Boolean longTerm) { @@ -38,10 +58,25 @@ public class StoreTokenGenerate extends AbstractTokenGenerate { if (!member.getHaveStore()) { throw new ServiceException(ResultCode.STORE_NOT_OPEN); } - AuthUser user = new AuthUser(member.getUsername(), member.getId(), member.getNickName(), UserEnums.STORE); - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(Store::getMemberId, member.getId()); - Store store = storeService.getOne(queryWrapper); + //根据会员id查询店员信息 + Clerk clerk = clerkService.getClerkByMemberId(member.getId()); + + AuthUser user = new AuthUser(member.getUsername(), member.getId(), UserEnums.STORE, member.getNickName(), clerk.getIsSuper(), clerk.getId()); + + if (clerk == null) { + throw new ServiceException(ResultCode.CLERK_NOT_FOUND_ERROR); + } + if (!clerk.getStatus()) { + throw new ServiceException(ResultCode.CLERK_DISABLED_ERROR); + } + List storeUserMenuVOS = storeMenuRoleService.findAllMenu(clerk.getId()); + //缓存权限列表 + cache.put(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.STORE) + clerk.getId(), this.permissionList(storeUserMenuVOS)); + //查询店铺信息 + Store store = storeService.getById(clerk.getStoreId()); + if (store == null) { + throw new ServiceException(ResultCode.STORE_NOT_OPEN); + } user.setStoreId(store.getId()); user.setStoreName(store.getStoreName()); return tokenUtil.createToken(username, user, longTerm, UserEnums.STORE); @@ -52,4 +87,65 @@ public class StoreTokenGenerate extends AbstractTokenGenerate { return tokenUtil.refreshToken(refreshToken, UserEnums.STORE); } + /** + * 获取用户权限 + * + * @param userMenuVOList + * @return + */ + private Map> permissionList(List userMenuVOList) { + Map> permission = new HashMap<>(2); + + List superPermissions = new ArrayList<>(); + List queryPermissions = new ArrayList<>(); + initPermission(superPermissions, queryPermissions); + + //循环权限菜单 + if (userMenuVOList != null && !userMenuVOList.isEmpty()) { + userMenuVOList.forEach(menu -> { + //循环菜单,赋予用户权限 + if (CharSequenceUtil.isNotEmpty(menu.getPermission())) { + //获取路径集合 + String[] permissionUrl = menu.getPermission().split(","); + //for循环路径集合 + for (String url : permissionUrl) { + //如果是超级权限 则计入超级权限 + if (Boolean.TRUE.equals(menu.getSuper())) { + //如果已有超级权限,则这里就不做权限的累加 + if (!superPermissions.contains(url)) { + superPermissions.add(url); + } + } + //否则计入浏览权限 + else { + //没有权限,则累加。 + if (!queryPermissions.contains(url)) { + queryPermissions.add(url); + } + } + } + } + //去除重复的权限 + queryPermissions.removeAll(superPermissions); + }); + } + permission.put(PermissionEnum.SUPER.name(), superPermissions); + permission.put(PermissionEnum.QUERY.name(), queryPermissions); + return permission; + } + + + /** + * 初始赋予的权限,查看权限包含首页流量统计权限, + * 超级权限包含个人信息维护,密码修改权限 + * + * @param superPermissions 超级权限 + * @param queryPermissions 查询权限 + */ + void initPermission(List superPermissions, List queryPermissions) { + + + } + + } diff --git a/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java b/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java index 0cc64d26..ba32a8a6 100644 --- a/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/store/serviceimpl/StoreServiceImpl.java @@ -10,7 +10,9 @@ import cn.lili.common.utils.BeanUtil; import cn.lili.common.vo.PageVO; import cn.lili.modules.goods.service.GoodsService; import cn.lili.modules.member.entity.dos.Member; +import cn.lili.modules.member.entity.dto.ClerkAddDTO; import cn.lili.modules.member.entity.dto.CollectionDTO; +import cn.lili.modules.member.service.ClerkService; import cn.lili.modules.member.service.MemberService; import cn.lili.modules.store.entity.dos.Store; import cn.lili.modules.store.entity.dos.StoreDetail; @@ -50,6 +52,12 @@ public class StoreServiceImpl extends ServiceImpl implements */ @Autowired private MemberService memberService; + + /** + * 店员 + */ + @Autowired + private ClerkService clerkService; /** * 商品 */ @@ -171,6 +179,13 @@ public class StoreServiceImpl extends ServiceImpl implements member.setHaveStore(true); member.setStoreId(id); memberService.updateById(member); + //创建店员 + ClerkAddDTO clerkAddDTO = new ClerkAddDTO(); + clerkAddDTO.setMemberId(member.getId()); + clerkAddDTO.setIsSuper(true); + clerkAddDTO.setShopkeeper(true); + clerkAddDTO.setStoreId(id); + clerkService.saveClerk(clerkAddDTO); //设定商家的结算日 storeDetailService.update(new LambdaUpdateWrapper() .eq(StoreDetail::getStoreId, id) diff --git a/framework/src/main/java/cn/lili/modules/system/token/ManagerTokenGenerate.java b/framework/src/main/java/cn/lili/modules/system/token/ManagerTokenGenerate.java index a8d96caa..32464c77 100644 --- a/framework/src/main/java/cn/lili/modules/system/token/ManagerTokenGenerate.java +++ b/framework/src/main/java/cn/lili/modules/system/token/ManagerTokenGenerate.java @@ -47,7 +47,6 @@ public class ManagerTokenGenerate extends AbstractTokenGenerate { AdminUser adminUser = adminUserService.findByUsername(username); AuthUser user = new AuthUser(adminUser.getUsername(), adminUser.getId(), UserEnums.MANAGER, adminUser.getNickName(), adminUser.getIsSuper()); - List userMenuVOList = roleMenuService.findAllMenu(user.getId()); //缓存权限列表 cache.put(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.MANAGER) + user.getId(), this.permissionList(userMenuVOList)); diff --git a/seller-api/src/main/java/cn/lili/controller/passport/StorePassportController.java b/seller-api/src/main/java/cn/lili/controller/passport/StorePassportController.java index a4cc3a96..b496271b 100644 --- a/seller-api/src/main/java/cn/lili/controller/passport/StorePassportController.java +++ b/seller-api/src/main/java/cn/lili/controller/passport/StorePassportController.java @@ -1,9 +1,12 @@ package cn.lili.controller.passport; +import cn.lili.common.aop.annotation.DemoSite; import cn.lili.common.enums.ResultCode; import cn.lili.common.enums.ResultUtil; import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.AuthUser; +import cn.lili.common.security.context.UserContext; import cn.lili.common.security.enums.UserEnums; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.member.entity.dos.Member; @@ -15,6 +18,7 @@ import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotNull; @@ -70,7 +74,11 @@ public class StorePassportController { @PostMapping("/modifyPass") public ResultMessage modifyPass(@NotNull(message = "旧密码不能为空") @RequestParam String password, @NotNull(message = "新密码不能为空") @RequestParam String newPassword) { - return ResultUtil.data(memberService.modifyPass(password, newPassword)); + AuthUser tokenUser = UserContext.getCurrentUser(); + if (tokenUser == null) { + throw new ServiceException(ResultCode.USER_NOT_LOGIN); + } + return ResultUtil.data(memberService.modifyPass(tokenUser.getId(), password, newPassword)); } @ApiOperation(value = "刷新token") @@ -80,4 +88,5 @@ public class StorePassportController { } + } diff --git a/seller-api/src/main/java/cn/lili/controller/permission/ClerkStoreController.java b/seller-api/src/main/java/cn/lili/controller/permission/ClerkStoreController.java new file mode 100644 index 00000000..74afd5fc --- /dev/null +++ b/seller-api/src/main/java/cn/lili/controller/permission/ClerkStoreController.java @@ -0,0 +1,155 @@ +package cn.lili.controller.permission; + +import cn.lili.common.aop.annotation.DemoSite; +import cn.lili.common.enums.ResultCode; +import cn.lili.common.enums.ResultUtil; +import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.context.UserContext; +import cn.lili.common.validation.Phone; +import cn.lili.common.vo.PageVO; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.member.entity.dos.Clerk; +import cn.lili.modules.member.entity.dos.Member; +import cn.lili.modules.member.entity.dto.*; +import cn.lili.modules.member.entity.vo.ClerkVO; +import cn.lili.modules.member.service.ClerkService; +import cn.lili.modules.member.service.MemberService; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.annotations.Delete; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +/** + * 店员接口 + * + * @author Chopper + * @since 2020/11/16 10:57 + */ +@Slf4j +@RestController +@Api(tags = "店员") +@RequestMapping("/store/clerk") +@Transactional(rollbackFor = Exception.class) +@Validated +public class ClerkStoreController { + @Autowired + private ClerkService clerkService; + + @Autowired + private MemberService memberService; + + + @GetMapping + @ApiOperation(value = "分页获取店员列表") + public ResultMessage> page(ClerkQueryDTO clerkQueryDTO, + PageVO pageVo) { + + IPage page = clerkService.clerkForPage(pageVo, clerkQueryDTO); + return ResultUtil.data(page); + } + + @GetMapping("/{id}") + @ApiOperation(value = "获取店员详细") + public ResultMessage get(@PathVariable String id) { + + return ResultUtil.data(clerkService.get(id)); + } + + + @PostMapping("/{mobile}/check") + @ApiOperation(value = "检测手机号码有效性") + public ResultMessage check(@PathVariable @Phone(message = "手机号码格式不正确") String mobile) { + return ResultUtil.data(clerkService.checkClerk(mobile)); + } + + + @PostMapping + @ApiOperation(value = "添加店员") + public ResultMessage add(@Valid ClerkAddDTO clerkAddDTO) { + int rolesMaxSize = 10; + try { + if (clerkAddDTO.getRoles() != null && clerkAddDTO.getRoles().size() >= rolesMaxSize) { + throw new ServiceException(ResultCode.PERMISSION_BEYOND_TEN); + } + //校验是否已经是会员 + Member member = memberService.findByMobile(clerkAddDTO.getMobile()); + if (member == null) { + //添加会员 + MemberAddDTO memberAddDTO = new MemberAddDTO(); + memberAddDTO.setMobile(clerkAddDTO.getMobile()); + memberAddDTO.setPassword(clerkAddDTO.getPassword()); + memberAddDTO.setUsername(clerkAddDTO.getUsername()); + member = memberService.addMember(memberAddDTO); + } else { + //校验要添加的会员是否已经是店主 + if (member.getHaveStore()) { + throw new ServiceException(ResultCode.STORE_APPLY_DOUBLE_ERROR); + } + //校验会员的有效性 + if (!member.getDisabled()) { + throw new ServiceException(ResultCode.USER_STATUS_ERROR); + } + } + //添加店员 + clerkAddDTO.setMemberId(member.getId()); + clerkAddDTO.setShopkeeper(false); + clerkAddDTO.setStoreId(UserContext.getCurrentUser().getStoreId()); + clerkService.saveClerk(clerkAddDTO); + //修改此会员拥有店铺 + List ids = new ArrayList<>(); + ids.add(member.getId()); + memberService.updateHaveShop(true, UserContext.getCurrentUser().getStoreId(), ids); + } catch (Exception e) { + log.error("添加店员出错", e); + } + return ResultUtil.success(); + } + + + @PutMapping("/{id}") + @ApiImplicitParam(name = "id", value = "店员id", required = true, paramType = "path") + @ApiOperation(value = "修改店员") + public ResultMessage edit(@PathVariable String id, @Valid ClerkEditDTO clerkEditDTO) { + clerkEditDTO.setId(id); + return ResultUtil.data(clerkService.updateClerk(clerkEditDTO)); + } + + @PutMapping(value = "/enable/{clerkId}") + @ApiOperation(value = "禁/启 用 店员") + @DemoSite + public ResultMessage disable(@ApiParam("用户唯一id标识") @PathVariable String clerkId, Boolean status) { + clerkService.disable(clerkId, status); + return ResultUtil.success(); + } + + + @DeleteMapping(value = "/delByIds/{ids}") + @ApiOperation(value = "删除店员") + public ResultMessage deleteClerk(@PathVariable List ids) { + clerkService.deleteClerk(ids); + return ResultUtil.success(); + } + + + @PostMapping(value = "/resetPassword/{ids}") + @ApiOperation(value = "重置密码") + @DemoSite + public ResultMessage resetPassword(@PathVariable List ids) { + clerkService.resetPassword(ids); + return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS); + } + + +} diff --git a/seller-api/src/main/java/cn/lili/controller/permission/StoreDepartmentController.java b/seller-api/src/main/java/cn/lili/controller/permission/StoreDepartmentController.java new file mode 100644 index 00000000..a5f21f6d --- /dev/null +++ b/seller-api/src/main/java/cn/lili/controller/permission/StoreDepartmentController.java @@ -0,0 +1,70 @@ +package cn.lili.controller.permission; + +import cn.lili.common.enums.ResultUtil; +import cn.lili.common.security.context.UserContext; +import cn.lili.common.vo.ResultMessage; +import cn.lili.common.vo.SearchVO; +import cn.lili.modules.member.entity.dos.StoreDepartment; +import cn.lili.modules.member.entity.vo.StoreDepartmentVO; +import cn.lili.modules.member.service.StoreDepartmentService; +import cn.lili.mybatis.util.PageUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 管理端,部门管理接口 + * + * @author Chopper + * @since 2020/11/22 12:06 + */ +@RestController +@Api(tags = "店铺端,部门管理接口") +@RequestMapping("/store/department") +public class StoreDepartmentController { + @Autowired + private StoreDepartmentService storeDepartmentService; + + @GetMapping(value = "/{id}") + @ApiOperation(value = "查看部门详情") + public ResultMessage get(@PathVariable String id) { + StoreDepartment storeDepartment = storeDepartmentService.getById(id); + return ResultUtil.data(storeDepartment); + } + + @GetMapping + @ApiOperation(value = "获取树状结构") + public ResultMessage> getByPage(StoreDepartment entity, + SearchVO searchVo) { + entity.setStoreId(UserContext.getCurrentUser().getStoreId()); + return ResultUtil.data(storeDepartmentService.tree(PageUtil.initWrapper(entity, searchVo))); + + } + + @PostMapping + @ApiOperation(value = "新增部门") + public ResultMessage save(StoreDepartment storeDepartment) { + storeDepartment.setStoreId(UserContext.getCurrentUser().getStoreId()); + storeDepartmentService.save(storeDepartment); + return ResultUtil.data(storeDepartment); + } + + @PutMapping("/{id}") + @ApiOperation(value = "更新部门") + public ResultMessage update(@PathVariable String id, StoreDepartment storeDepartment) { + storeDepartment.setId(id); + storeDepartmentService.update(storeDepartment); + return ResultUtil.data(storeDepartment); + } + + @DeleteMapping(value = "/{ids}") + @ApiOperation(value = "删除部门") + public ResultMessage delAllByIds(@PathVariable List ids) { + storeDepartmentService.deleteByIds(ids); + return ResultUtil.success(); + } +} diff --git a/seller-api/src/main/java/cn/lili/controller/permission/StoreDepartmentRoleController.java b/seller-api/src/main/java/cn/lili/controller/permission/StoreDepartmentRoleController.java new file mode 100644 index 00000000..d395abaf --- /dev/null +++ b/seller-api/src/main/java/cn/lili/controller/permission/StoreDepartmentRoleController.java @@ -0,0 +1,42 @@ +package cn.lili.controller.permission; + +import cn.lili.common.enums.ResultUtil; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.member.entity.dos.StoreDepartmentRole; +import cn.lili.modules.member.service.StoreDepartmentRoleService; +import cn.lili.modules.permission.entity.dos.DepartmentRole; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 店铺端,部门角色接口 + * + * @author Chopper + * @since 2020/11/22 14:05 + */ +@RestController +@Api(tags = "店铺端,部门角色接口") +@RequestMapping("/store/departmentRole") +public class StoreDepartmentRoleController { + @Autowired + private StoreDepartmentRoleService storeDepartmentRoleService; + + @GetMapping(value = "/{departmentId}") + @ApiOperation(value = "查看部门拥有的角色") + public ResultMessage> get(@PathVariable String departmentId) { + return ResultUtil.data(storeDepartmentRoleService.listByDepartmentId(departmentId)); + } + + @PutMapping("/{departmentId}") + @ApiOperation(value = "更新部门角色") + public ResultMessage update(@PathVariable String departmentId, @RequestBody List storeDepartmentRoles) { + storeDepartmentRoleService.updateByDepartmentId(departmentId, storeDepartmentRoles); + return ResultUtil.success(); + } + +} diff --git a/seller-api/src/main/java/cn/lili/controller/permission/StoreMenuController.java b/seller-api/src/main/java/cn/lili/controller/permission/StoreMenuController.java new file mode 100644 index 00000000..bc4ee683 --- /dev/null +++ b/seller-api/src/main/java/cn/lili/controller/permission/StoreMenuController.java @@ -0,0 +1,49 @@ +package cn.lili.controller.permission; + +import cn.lili.common.aop.annotation.DemoSite; +import cn.lili.common.enums.ResultUtil; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.member.entity.vo.StoreMenuVO; +import cn.lili.modules.member.service.StoreMenuService; +import cn.lili.modules.permission.entity.dos.Menu; +import cn.lili.modules.permission.entity.dto.MenuSearchParams; +import cn.lili.modules.permission.entity.vo.MenuVO; +import cn.lili.modules.permission.service.MenuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 管理端,菜单管理接口 + * + * @author Chopper + * @since 2020/11/20 12:07 + */ +@Slf4j +@RestController +@Api(tags = "店铺端,菜单管理接口") +@RequestMapping("/store/menu") +public class StoreMenuController { + + @Autowired + private StoreMenuService storeMenuService; + + + @ApiOperation(value = "获取所有菜单") + @GetMapping("/tree") + public ResultMessage> getAllMenuList() { + return ResultUtil.data(storeMenuService.tree()); + } + + @ApiOperation(value = "获取所有菜单") + @GetMapping("/memberMenu") + public ResultMessage> memberMenu() { + return ResultUtil.data(storeMenuService.findUserTree()); + } +} diff --git a/seller-api/src/main/java/cn/lili/controller/permission/StoreMenuRoleController.java b/seller-api/src/main/java/cn/lili/controller/permission/StoreMenuRoleController.java new file mode 100644 index 00000000..ae4f99f7 --- /dev/null +++ b/seller-api/src/main/java/cn/lili/controller/permission/StoreMenuRoleController.java @@ -0,0 +1,43 @@ +package cn.lili.controller.permission; + +import cn.lili.common.enums.ResultUtil; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.member.entity.dos.StoreMenuRole; +import cn.lili.modules.member.service.StoreMenuRoleService; +import cn.lili.modules.permission.entity.dos.RoleMenu; +import cn.lili.modules.permission.service.RoleMenuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 店铺端,角色菜单接口 + * + * @author Chopper + * @since 2020/11/22 11:40 + */ +@RestController +@Api(tags = "店铺端,角色菜单接口") +@RequestMapping("/store/roleMenu") +public class StoreMenuRoleController { + @Autowired + private StoreMenuRoleService storeMenuRoleService; + + @GetMapping(value = "/{roleId}") + @ApiOperation(value = "查看某角色拥有到菜单") + public ResultMessage> get(@PathVariable String roleId) { + return ResultUtil.data(storeMenuRoleService.findByRoleId(roleId)); + } + + @PostMapping(value = "/{roleId}") + @ApiOperation(value = "保存角色菜单") + public ResultMessage save(@PathVariable String roleId, @RequestBody List roleMenus) { + storeMenuRoleService.updateRoleMenu(roleId, roleMenus); + return ResultUtil.success(); + } + +} diff --git a/seller-api/src/main/java/cn/lili/controller/permission/StoreRoleController.java b/seller-api/src/main/java/cn/lili/controller/permission/StoreRoleController.java new file mode 100644 index 00000000..83e5761e --- /dev/null +++ b/seller-api/src/main/java/cn/lili/controller/permission/StoreRoleController.java @@ -0,0 +1,65 @@ +package cn.lili.controller.permission; + +import cn.lili.common.enums.ResultUtil; +import cn.lili.common.security.context.UserContext; +import cn.lili.common.vo.PageVO; +import cn.lili.common.vo.ResultMessage; +import cn.lili.modules.member.entity.dos.StoreRole; +import cn.lili.modules.member.service.StoreRoleService; +import cn.lili.modules.permission.entity.dos.Role; +import cn.lili.modules.permission.service.RoleService; +import cn.lili.mybatis.util.PageUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 店铺端,角色管理接口 + * + * @author Chopper + * @since 2020/11/20 18:50 + */ +@RestController +@Api(tags = "店铺端,店铺角色管理接口") +@RequestMapping("/store/role") +public class StoreRoleController { + @Autowired + private StoreRoleService storeRoleService; + + @PostMapping + @ApiOperation(value = "添加角色") + public ResultMessage add(StoreRole storeRole) { + storeRoleService.saveStoreRole(storeRole); + return ResultUtil.data(storeRole); + } + + @GetMapping + @ApiOperation(value = "查询店铺角色") + public ResultMessage page(PageVO pageVo, StoreRole storeRole) { + storeRole.setStoreId(UserContext.getCurrentUser().getStoreId()); + Page page = storeRoleService.page(PageUtil.initPage(pageVo), PageUtil.initWrapper(storeRole)); + return ResultUtil.data(page); + } + + @PutMapping("/{roleId}") + @ApiOperation(value = "编辑店铺角色") + public ResultMessage edit(@PathVariable String roleId, StoreRole storeRole) { + storeRole.setId(roleId); + storeRoleService.update(storeRole); + return ResultUtil.data(storeRole); + } + + @DeleteMapping(value = "/{ids}") + @ApiOperation(value = "批量删除店铺角色") + public ResultMessage delByIds(@PathVariable List ids) { + storeRoleService.deleteRoles(ids); + return ResultUtil.success(); + } + + +} diff --git a/seller-api/src/main/java/cn/lili/security/StoreAuthenticationFilter.java b/seller-api/src/main/java/cn/lili/security/StoreAuthenticationFilter.java index 7b20ea1f..5444a4fc 100755 --- a/seller-api/src/main/java/cn/lili/security/StoreAuthenticationFilter.java +++ b/seller-api/src/main/java/cn/lili/security/StoreAuthenticationFilter.java @@ -1,9 +1,11 @@ package cn.lili.security; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; import cn.lili.cache.Cache; import cn.lili.cache.CachePrefix; import cn.lili.common.security.AuthUser; +import cn.lili.common.security.enums.PermissionEnum; import cn.lili.common.security.enums.SecurityEnum; import cn.lili.common.security.enums.UserEnums; import cn.lili.common.security.token.SecretKeyUtil; @@ -20,7 +22,10 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.util.PatternMatchUtils; +import org.springframework.web.bind.annotation.RequestMethod; +import javax.naming.NoPermissionException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -28,6 +33,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @author Chopper @@ -46,19 +52,20 @@ public class StoreAuthenticationFilter extends BasicAuthenticationFilter { @SneakyThrows @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - - String accessToken = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue()); - if (StrUtil.isBlank(accessToken)) { + //从header中获取jwt + String jwt = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue()); + //如果没有token 则return + if (StrUtil.isBlank(jwt)) { chain.doFilter(request, response); return; } - try { - UsernamePasswordAuthenticationToken authentication = getAuthentication(accessToken, response); + //获取用户信息,存入context + UsernamePasswordAuthenticationToken authentication = getAuthentication(jwt, response); + //自定义权限过滤 + if (authentication != null) { + customAuthentication(request, response, authentication); SecurityContextHolder.getContext().setAuthentication(authentication); - } catch (Exception e) { - log.error(e.getMessage()); } - chain.doFilter(request, response); } @@ -100,5 +107,60 @@ public class StoreAuthenticationFilter extends BasicAuthenticationFilter { } return null; } + + + /** + * 自定义权限过滤 + * + * @param request 请求 + * @param response 响应 + * @param authentication 用户信息 + */ + private void customAuthentication(HttpServletRequest request, HttpServletResponse response, UsernamePasswordAuthenticationToken authentication) throws NoPermissionException { + AuthUser authUser = (AuthUser) authentication.getDetails(); + String requestUrl = request.getRequestURI(); + + + //如果不是超级管理员, 则鉴权 + if (!authUser.getIsSuper()) { + //获取缓存中的权限 + Map> permission = (Map>) cache.get(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.STORE) + authUser.getId()); + + //获取数据(GET 请求)权限 + if (request.getMethod().equals(RequestMethod.GET.name())) { + //如果用户的超级权限和查阅权限都不包含当前请求的api + if (match(permission.get(PermissionEnum.SUPER.name()), requestUrl) || + match(permission.get(PermissionEnum.QUERY.name()), requestUrl)) { + } else { + ResponseUtil.output(response, ResponseUtil.resultMap(false, 400, "权限不足")); + log.error("当前请求路径:{},所拥有权限:{}", requestUrl, JSONUtil.toJsonStr(permission)); + throw new NoPermissionException("权限不足"); + } + } + //非get请求(数据操作) 判定鉴权 + else { + if (!match(permission.get(PermissionEnum.SUPER.name()), requestUrl)) { + ResponseUtil.output(response, ResponseUtil.resultMap(false, 400, "权限不足")); + log.error("当前请求路径:{},所拥有权限:{}", requestUrl, JSONUtil.toJsonStr(permission)); + throw new NoPermissionException("权限不足"); + } + } + } + } + + /** + * 校验权限 + * + * @param permissions 权限集合 + * @param url 请求地址 + * @return 是否拥有权限 + */ + boolean match(List permissions, String url) { + if (permissions == null || permissions.isEmpty()) { + return false; + } + return PatternMatchUtils.simpleMatch(permissions.toArray(new String[0]), url); + } + }