测试环境配置及带租房的登录功能
This commit is contained in:
@@ -14,7 +14,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.xml.ws.soap.Addressing;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
package com.zf.foodpurchase.fdsafe.wxapp.common;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.zf.foodpurchase.common.config.RuoYiConfig;
|
||||
import com.zf.foodpurchase.common.constant.Constants;
|
||||
import com.zf.foodpurchase.common.constant.UserConstants;
|
||||
import com.zf.foodpurchase.common.core.controller.BaseController;
|
||||
import com.zf.foodpurchase.common.core.domain.AjaxResult;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.LoginWxUser;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.User;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.WxAppUserVO;
|
||||
import com.zf.foodpurchase.common.core.domain.model.WxAppLoginBody;
|
||||
import com.zf.foodpurchase.common.core.domain.model.WxAppLoginUser;
|
||||
import com.zf.foodpurchase.common.exception.ServiceException;
|
||||
import com.zf.foodpurchase.common.exception.user.UserPasswordNotMatchException;
|
||||
import com.zf.foodpurchase.common.utils.MessageUtils;
|
||||
import com.zf.foodpurchase.common.utils.SecurityUtils;
|
||||
import com.zf.foodpurchase.common.utils.StringUtils;
|
||||
import com.zf.foodpurchase.common.utils.file.FileUploadUtils;
|
||||
import com.zf.foodpurchase.common.utils.file.MimeTypeUtils;
|
||||
import com.zf.foodpurchase.fdsafe.entity.WxAppUser;
|
||||
import com.zf.foodpurchase.fdsafe.service.IWxAppUserService;
|
||||
import com.zf.foodpurchase.fdsafe.vo.WxAppUserViewVO;
|
||||
import com.zf.foodpurchase.framework.manager.AsyncManager;
|
||||
import com.zf.foodpurchase.framework.manager.factory.AsyncFactory;
|
||||
import com.zf.foodpurchase.framework.web.service.WxAppLoginService;
|
||||
import com.zf.foodpurchase.framework.web.service.WxAppTokenService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author:lilj
|
||||
* @date:2025/5/12
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/wxapp/userLogin")
|
||||
public class WxAppUserLoginController extends BaseController {
|
||||
@Autowired
|
||||
private IWxAppUserService wxAppUserService;
|
||||
|
||||
@Autowired
|
||||
private WxAppTokenService wxAppTokenService;
|
||||
|
||||
@Autowired
|
||||
private WxAppLoginService wxAppLoginService;
|
||||
private WxAppUserVO loginWxUser;
|
||||
|
||||
@PostMapping("/login")
|
||||
public AjaxResult login(@RequestBody @Valid WxAppLoginBody wxAppLoginBody) {
|
||||
String token = wxAppLoginService.login(wxAppLoginBody);
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@GetMapping("/getCurrentUser")
|
||||
public AjaxResult getCurrentUser() {
|
||||
WxAppLoginUser loginWxUser = getWxAppLoginUser();
|
||||
WxAppUserVO user = loginWxUser.getUser();
|
||||
AjaxResult response = success("查询成功");
|
||||
response.put("user", user);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可修改项:用户密码,昵称,头像,性别
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/updateUser")
|
||||
public AjaxResult updateUser(@RequestBody WxAppUserViewVO user) {
|
||||
if (user == null || user.getId() == null) {
|
||||
return error("用户id不能为空");
|
||||
}
|
||||
LambdaUpdateWrapper<WxAppUser> updateWrapper = new LambdaUpdateWrapper<WxAppUser>();
|
||||
updateWrapper.eq(WxAppUser::getId, user.getId());
|
||||
updateWrapper.set(WxAppUser::getNickname, user.getNickname());
|
||||
updateWrapper.set(WxAppUser::getRealName, user.getRealName());
|
||||
updateWrapper.set(WxAppUser::getAvatarUrl, user.getAvatarUrl());
|
||||
updateWrapper.set(WxAppUser::getGender, user.getGender());
|
||||
updateWrapper.set(WxAppUser::getUpdateTime, new Date());
|
||||
boolean isUpdate = wxAppUserService.update(updateWrapper);
|
||||
if (!isUpdate) {
|
||||
return error("修改失败");
|
||||
}
|
||||
WxAppUserVO newUser = wxAppUserService.getUserVOById(user.getId());
|
||||
WxAppLoginUser loginUser = getWxAppLoginUser();
|
||||
// 设置部门名称
|
||||
WxAppUserVO oldUser = loginUser.getUser();
|
||||
newUser.setDeptName(oldUser.getDeptName());
|
||||
loginUser.setUser(newUser);
|
||||
|
||||
wxAppTokenService.setLoginWxAppUser(loginUser);
|
||||
return isUpdate ? success("修改成功") : error("修改失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码
|
||||
*/
|
||||
@PostMapping("/updateUserPassword")
|
||||
public AjaxResult updateUserPassword(@RequestBody WxAppUserViewVO user) {
|
||||
if (user == null || user.getId() == null) {
|
||||
return error("用户id不能为空");
|
||||
}
|
||||
pwdCheck(user.getNewPassword());
|
||||
WxAppUser old = wxAppUserService.getById(user.getId());
|
||||
if (old == null) {
|
||||
return error("用户不存在");
|
||||
}
|
||||
// 校验密码是否正确
|
||||
boolean isMatch = SecurityUtils.matchesPassword(user.getPassword(), old.getPassword());
|
||||
if (!isMatch) {
|
||||
throw new ServiceException("原密码有误");
|
||||
}
|
||||
|
||||
WxAppUser updateUser = new WxAppUser();
|
||||
updateUser.setId(user.getId());
|
||||
updateUser.setPassword(SecurityUtils.encryptPassword(user.getNewPassword()));
|
||||
boolean isUpdate = wxAppUserService.updateById(updateUser);
|
||||
return isUpdate ? success("密码修改成功") : error("密码修改失败");
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/logout")
|
||||
public AjaxResult logout() {
|
||||
WxAppLoginUser wxAppLoginUser = getWxAppLoginUser();
|
||||
if (wxAppLoginUser != null) {
|
||||
String token = wxAppLoginUser.getToken();
|
||||
wxAppTokenService.delLoginWxAppUser(token);
|
||||
}
|
||||
return AjaxResult.success("退出登录成功");
|
||||
}
|
||||
|
||||
public void pwdCheck(String userPwd) {
|
||||
if (StringUtils.isBlank(userPwd)) {
|
||||
throw new ServiceException("新密码不能为空");
|
||||
}
|
||||
// 密码如果不在指定范围内 错误
|
||||
if (userPwd.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||
|| userPwd.length() > UserConstants.PASSWORD_MAX_LENGTH) {
|
||||
throw new ServiceException("新密码位数应大于" + UserConstants.PASSWORD_MIN_LENGTH + ",小于" + UserConstants.PASSWORD_MAX_LENGTH + "位");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信头像上传
|
||||
*/
|
||||
@PostMapping(value = "/avatar", produces = "application/json;charset=UTF-8")
|
||||
public AjaxResult avatar(MultipartFile file) throws Exception {
|
||||
if (!file.isEmpty()) {
|
||||
WxAppLoginUser loginWxUser = getWxAppLoginUser();
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath();
|
||||
// D:/ruoyi/wxprofile/avatar
|
||||
String avatar = FileUploadUtils.upload(filePath, file, MimeTypeUtils.IMAGE_EXTENSION);
|
||||
|
||||
avatar = RuoYiConfig.getImagePrefix() + avatar;
|
||||
return AjaxResult.success().put("avatarUrl", avatar);
|
||||
}
|
||||
return error("上传图片异常");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -63,12 +63,7 @@ public class SysLoginController {
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public AjaxResult login(@RequestBody LoginBody loginBody) {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
// 生成令牌
|
||||
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
|
||||
loginBody.getUuid());
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
return ajax;
|
||||
return loginService.login(loginBody.getTenantId(), loginBody.getUsername(), loginBody.getPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,16 +9,16 @@ spring:
|
||||
# url: jdbc:mysql://localhost:3306/zf_shopping_mall?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
# username: root
|
||||
# password: root123456
|
||||
url: jdbc:mysql://125.46.39.9:3306/zf_school_food?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://39.165.209.170:3307/zf_school_food?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: wXn*QFs_6aNvFq@qDr.gPYsfBL-XN_o2
|
||||
password: zheng_wXn_fan*QFs_6aNvFq@keji_qDr.gPYsfBL
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
#enabled: false
|
||||
url: jdbc:mysql://39.165.209.170:3307/zf_shopping_mall?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: zheng_wXn_fan*QFs_6aNvFq@keji_qDr.gPYsfBL
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.zf.foodpurchase.common.constant;
|
||||
|
||||
/**
|
||||
* 租户常量信息
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface TenantConstants {
|
||||
|
||||
/**
|
||||
* 超级管理员ID
|
||||
*/
|
||||
Long SUPER_ADMIN_ID = 1L;
|
||||
|
||||
/**
|
||||
* 超级管理员角色 roleKey
|
||||
*/
|
||||
String SUPER_ADMIN_ROLE_KEY = "super_admin";
|
||||
|
||||
/**
|
||||
* 租户管理员角色 roleKey
|
||||
*/
|
||||
String TENANT_ADMIN_ROLE_KEY = "tenant_admin";
|
||||
|
||||
/**
|
||||
* 租户管理员角色名称
|
||||
*/
|
||||
String TENANT_ADMIN_ROLE_NAME = "租户管理员";
|
||||
|
||||
/**
|
||||
* 默认租户ID
|
||||
*/
|
||||
String DEFAULT_TENANT_ID = "000000";
|
||||
|
||||
}
|
||||
@@ -25,6 +25,10 @@ public class SysDept extends BaseEntity
|
||||
/** 父商户ID */
|
||||
private Long parentId;
|
||||
|
||||
private String tenantId;
|
||||
|
||||
private String isTenant;
|
||||
|
||||
/** 祖级列表 */
|
||||
private String ancestors;
|
||||
|
||||
@@ -235,11 +239,29 @@ public class SysDept extends BaseEntity
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
public String getIsTenant() {
|
||||
return isTenant;
|
||||
}
|
||||
|
||||
public void setIsTenant(String isTenant) {
|
||||
this.isTenant = isTenant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("deptId", getDeptId())
|
||||
.append("parentId", getParentId())
|
||||
.append("tenantId", getTenantId())
|
||||
.append("isTenant", getIsTenant())
|
||||
.append("ancestors", getAncestors())
|
||||
.append("deptName", getDeptName())
|
||||
.append("orderNum", getOrderNum())
|
||||
|
||||
@@ -35,6 +35,8 @@ public class SysRole extends BaseEntity
|
||||
@Excel(name = "角色排序")
|
||||
private Integer roleSort;
|
||||
|
||||
private String tenantId;
|
||||
|
||||
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
|
||||
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
||||
private String dataScope;
|
||||
@@ -219,6 +221,14 @@ public class SysRole extends BaseEntity
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
@@ -226,6 +236,7 @@ public class SysRole extends BaseEntity
|
||||
.append("roleName", getRoleName())
|
||||
.append("roleKey", getRoleKey())
|
||||
.append("roleSort", getRoleSort())
|
||||
.append("tenantId", getTenantId())
|
||||
.append("dataScope", getDataScope())
|
||||
.append("menuCheckStrictly", isMenuCheckStrictly())
|
||||
.append("deptCheckStrictly", isDeptCheckStrictly())
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.zf.foodpurchase.common.core.domain.entity;
|
||||
|
||||
|
||||
import com.zf.foodpurchase.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 租户业务对象 sys_tenant
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysTenantBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@NotNull(message = "id不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
@NotBlank(message = "联系人不能为空")
|
||||
private String contactUserName;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
@NotBlank(message = "联系电话不能为空")
|
||||
private String contactPhone;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
@NotBlank(message = "企业名称不能为空")
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 用户名(创建系统用户)
|
||||
*/
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码(创建系统用户)
|
||||
*/
|
||||
@NotBlank(message = "密码不能为空")
|
||||
// @Pattern(regexp = RegexConstants.PASSWORD, message = "{user.password.format.valid}", groups = { AddGroup.class })
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 统一社会信用代码
|
||||
*/
|
||||
private String licenseNumber;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 企业简介
|
||||
*/
|
||||
private String intro;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 租户套餐编号
|
||||
*/
|
||||
@NotNull(message = "租户套餐不能为空")
|
||||
private Long packageId;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 用户数量(-1不限制)
|
||||
*/
|
||||
private Long accountCount;
|
||||
|
||||
/**
|
||||
* 租户状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
private Long deptId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.zf.foodpurchase.common.core.domain.entity;
|
||||
|
||||
|
||||
import com.zf.foodpurchase.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 租户套餐业务对象 sys_tenant_package
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysTenantPackageBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 租户套餐id
|
||||
*/
|
||||
private Long packageId;
|
||||
|
||||
/**
|
||||
* 套餐名称
|
||||
*/
|
||||
private String packageName;
|
||||
|
||||
/**
|
||||
* 关联菜单id
|
||||
*/
|
||||
private Long[] menuIds;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 菜单树选择项是否关联显示
|
||||
*/
|
||||
private Boolean menuCheckStrictly;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.zf.foodpurchase.common.core.domain.entity;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 租户视图对象 sys_tenant
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Data
|
||||
public class SysTenantVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
private String contactUserName;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String contactPhone;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 统一社会信用代码
|
||||
*/
|
||||
private String licenseNumber;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 企业简介
|
||||
*/
|
||||
private String intro;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 租户套餐编号
|
||||
*/
|
||||
private Long packageId;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 用户数量(-1不限制)
|
||||
*/
|
||||
private Long accountCount;
|
||||
|
||||
/**
|
||||
* 租户状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
private Long deptId;
|
||||
|
||||
private Long createDept;
|
||||
}
|
||||
@@ -29,6 +29,16 @@ public class SysUser extends BaseEntity {
|
||||
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 学校id
|
||||
*/
|
||||
private Integer organiId;
|
||||
|
||||
/**
|
||||
* 租户id
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
@@ -369,10 +379,28 @@ public class SysUser extends BaseEntity {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public Integer getOrganiId() {
|
||||
return organiId;
|
||||
}
|
||||
|
||||
public void setOrganiId(Integer organiId) {
|
||||
this.organiId = organiId;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("userId", getUserId())
|
||||
.append("organiId", getOrganiId())
|
||||
.append("tenantId", getTenantId())
|
||||
.append("deptId", getDeptId())
|
||||
.append("userName", getUserName())
|
||||
.append("nickName", getNickName())
|
||||
|
||||
@@ -7,6 +7,9 @@ package com.zf.foodpurchase.common.core.domain.model;
|
||||
*/
|
||||
public class LoginBody
|
||||
{
|
||||
|
||||
private String tenantId;
|
||||
/**
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@@ -66,4 +69,12 @@ public class LoginBody
|
||||
{
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.zf.foodpurchase.common.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class PageResult implements Serializable {
|
||||
|
||||
private Integer pageIndex;//当前页
|
||||
private Integer pages;//总页数
|
||||
private Long totles;//总条数
|
||||
private List result; //结果集
|
||||
|
||||
public Integer getPageIndex() {
|
||||
return pageIndex;
|
||||
}
|
||||
|
||||
public void setPageIndex(Integer pageIndex) {
|
||||
this.pageIndex = pageIndex;
|
||||
}
|
||||
|
||||
public Integer getPages() {
|
||||
return pages;
|
||||
}
|
||||
|
||||
public void setPages(Integer pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
public Long getTotles() {
|
||||
return totles;
|
||||
}
|
||||
|
||||
public void setTotles(Long totles) {
|
||||
this.totles = totles;
|
||||
}
|
||||
|
||||
public List getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package com.zf.foodpurchase.common.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import com.zf.foodpurchase.common.constant.Constants;
|
||||
import com.zf.foodpurchase.common.core.text.StrFormatter;
|
||||
@@ -681,4 +678,20 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static List<Long> commaStrToLongList(String str) {
|
||||
// 1. 处理空值/空字符串:直接返回空集合,避免NPE
|
||||
if (str == null || str.trim().isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 2. 拆分+清理空格+转换为Long+收集为List
|
||||
return Arrays.asList(str.split(",")) // 按逗号拆分字符串为数组
|
||||
.stream() // 转为流处理
|
||||
.map(String::trim) // 去除每个元素的前后空格(处理" 4 , 5 "的情况)
|
||||
.filter(s -> !s.isEmpty()) // 过滤拆分后空字符串(比如",,6"拆分出的空元素)
|
||||
.map(Long::valueOf) // 字符串转Long(非数字会抛NumberFormatException)
|
||||
.collect(Collectors.toList()); // 收集为List<Long>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.zf.foodpurchase.framework.config;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.zf.foodpurchase.framework.service.ClientUserDetailsService;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
public class ClientLoginAuthProvider extends AbstractUserDetailsAuthenticationProvider {
|
||||
|
||||
|
||||
private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
|
||||
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
/**
|
||||
* The password used to perform {@link PasswordEncoder#matches(CharSequence, String)}
|
||||
* on when the user is not found to avoid SEC-2056. This is necessary, because some
|
||||
* {@link PasswordEncoder} implementations will short circuit if the password is not
|
||||
* in a valid format.
|
||||
*/
|
||||
private volatile String userNotFoundEncodedPassword;
|
||||
|
||||
private ClientUserDetailsService userDetailsService;
|
||||
|
||||
private UserDetailsPasswordService userDetailsPasswordService;
|
||||
|
||||
public ClientLoginAuthProvider(ClientUserDetailsService clientUserDetailsService) {
|
||||
this.userDetailsService = clientUserDetailsService;
|
||||
setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
||||
UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
|
||||
if (authentication.getCredentials() == null) {
|
||||
this.logger.debug("Failed to authenticate since no credentials provided");
|
||||
throw new BadCredentialsException(this.messages
|
||||
.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
|
||||
}
|
||||
String presentedPassword = authentication.getCredentials().toString();
|
||||
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
|
||||
this.logger.debug("Failed to authenticate since password does not match stored value");
|
||||
throw new BadCredentialsException(this.messages
|
||||
.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doAfterPropertiesSet() {
|
||||
Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
|
||||
CustomUsernamePasswordAuthenticationToken auth = (CustomUsernamePasswordAuthenticationToken) authentication;
|
||||
|
||||
//多个参数
|
||||
UserDetails loadedUser = userDetailsService.loadUserByUsername(username,auth.getTenantId());
|
||||
|
||||
if (loadedUser == null) {
|
||||
throw new InternalAuthenticationServiceException(
|
||||
"UserDetailsService returned null, which is an interface contract violation");
|
||||
}
|
||||
return loadedUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Authentication createSuccessAuthentication(Object principal, Authentication authentication,
|
||||
UserDetails user) {
|
||||
boolean upgradeEncoding = this.userDetailsPasswordService != null
|
||||
&& this.passwordEncoder.upgradeEncoding(user.getPassword());
|
||||
if (upgradeEncoding) {
|
||||
String presentedPassword = authentication.getCredentials().toString();
|
||||
String newPassword = this.passwordEncoder.encode(presentedPassword);
|
||||
user = this.userDetailsPasswordService.updatePassword(user, newPassword);
|
||||
}
|
||||
return super.createSuccessAuthentication(principal, authentication, user);
|
||||
}
|
||||
|
||||
private void prepareTimingAttackProtection() {
|
||||
if (this.userNotFoundEncodedPassword == null) {
|
||||
this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) {
|
||||
if (authentication.getCredentials() != null) {
|
||||
String presentedPassword = authentication.getCredentials().toString();
|
||||
this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the PasswordEncoder instance to be used to encode and validate passwords. If
|
||||
* not set, the password will be compared using
|
||||
* {@link PasswordEncoderFactories#createDelegatingPasswordEncoder()}
|
||||
* @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
|
||||
* types.
|
||||
*/
|
||||
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||
Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.userNotFoundEncodedPassword = null;
|
||||
}
|
||||
|
||||
protected PasswordEncoder getPasswordEncoder() {
|
||||
return this.passwordEncoder;
|
||||
}
|
||||
|
||||
public void setUserDetailsService(ClientUserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
protected ClientUserDetailsService getUserDetailsService() {
|
||||
return this.userDetailsService;
|
||||
}
|
||||
|
||||
public void setUserDetailsPasswordService(UserDetailsPasswordService userDetailsPasswordService) {
|
||||
this.userDetailsPasswordService = userDetailsPasswordService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.zf.foodpurchase.framework.config;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
|
||||
public class CustomUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {
|
||||
private final String tenantId;
|
||||
|
||||
public CustomUsernamePasswordAuthenticationToken(Object principal, Object credentials, String tenantId) {
|
||||
super(principal, credentials);
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zf.foodpurchase.framework.config;
|
||||
|
||||
import com.zf.foodpurchase.framework.service.ClientUserDetailsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -9,8 +10,12 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
@@ -23,28 +28,15 @@ import com.zf.foodpurchase.framework.security.filter.JwtAuthenticationTokenFilte
|
||||
import com.zf.foodpurchase.framework.security.handle.AuthenticationEntryPointImpl;
|
||||
import com.zf.foodpurchase.framework.security.handle.LogoutSuccessHandlerImpl;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* spring security配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||
@Configuration
|
||||
public class SecurityConfig
|
||||
{
|
||||
/**
|
||||
* 自定义用户认证逻辑
|
||||
*/
|
||||
@Autowired
|
||||
@Qualifier("userDetailsServiceImpl")
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
/**
|
||||
* 自定义微信小程序/APP认证逻辑类
|
||||
*/
|
||||
@Autowired
|
||||
@Qualifier("wxAppUserDetailsService")
|
||||
private UserDetailsService wxAppUserDetailsService;
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
/**
|
||||
* 认证失败处理类
|
||||
@@ -75,31 +67,22 @@ public class SecurityConfig
|
||||
*/
|
||||
@Autowired
|
||||
private PermitAllUrlProperties permitAllUrl;
|
||||
/**
|
||||
* 身份验证实现
|
||||
*/
|
||||
@Bean("authenticationManager")
|
||||
@Primary
|
||||
public AuthenticationManager authenticationManager()
|
||||
{
|
||||
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
|
||||
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
|
||||
daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
|
||||
AuthenticationManager manager=new ProviderManager(daoAuthenticationProvider);
|
||||
return manager;
|
||||
|
||||
|
||||
@Resource
|
||||
private ClientUserDetailsService clientUserDetailsService;
|
||||
|
||||
@Bean
|
||||
public ClientLoginAuthProvider clientLoginAuthProvider(){
|
||||
ClientLoginAuthProvider provider = new ClientLoginAuthProvider(clientUserDetailsService);
|
||||
provider.setPasswordEncoder(bCryptPasswordEncoder());
|
||||
return provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* wxApp登录身份验证实现
|
||||
*/
|
||||
@Bean("wxAppAuthenticationManager")
|
||||
public AuthenticationManager wxAppAuthenticationManager()
|
||||
{
|
||||
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
|
||||
daoAuthenticationProvider.setUserDetailsService(wxAppUserDetailsService);
|
||||
daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
|
||||
AuthenticationManager manager=new ProviderManager(daoAuthenticationProvider);
|
||||
return manager;
|
||||
@Bean
|
||||
@Override
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,49 +100,45 @@ public class SecurityConfig
|
||||
* rememberMe | 允许通过remember-me登录的用户访问
|
||||
* authenticated | 用户登录后可访问
|
||||
*/
|
||||
@Bean
|
||||
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
|
||||
{
|
||||
return httpSecurity
|
||||
// CSRF禁用,因为不使用session
|
||||
.csrf(csrf -> csrf.disable())
|
||||
// 禁用HTTP响应标头
|
||||
.headers((headersCustomizer) -> {
|
||||
headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
|
||||
})
|
||||
// 认证失败处理类
|
||||
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
|
||||
// 基于token,所以不需要session
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
// 注解标记允许匿名访问的url
|
||||
.authorizeHttpRequests((requests) -> {
|
||||
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
||||
@Override
|
||||
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
||||
|
||||
// 注解标记允许匿名访问的url
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
|
||||
permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
|
||||
|
||||
httpSecurity
|
||||
// CSRF禁用,因为不使用session
|
||||
.csrf().disable()
|
||||
// 认证失败处理类
|
||||
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
|
||||
// 基于token,所以不需要session
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||
// 过滤请求
|
||||
.authorizeRequests()
|
||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||
requests.antMatchers("/login", "/register", "/captchaImage","/wx/user/mockLogin","/wx/user/login","/wxapp/userLogin/login").permitAll()
|
||||
// 静态资源,可匿名访问
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
// 微信静态资源访问不被拦截
|
||||
.antMatchers("/wx/static/**","/wx/payApi/").permitAll()
|
||||
// 部分接口开放,不受权限访问限制
|
||||
.antMatchers("/wx/area/**").permitAll()
|
||||
// 微信体验功能,部分接口权限放开
|
||||
// 首页查询商品查询,轮播图查询,类别查询,按类别查询商品接口
|
||||
.antMatchers("/wx/products/indexProducts","/wx/dict/type/product_category","/wx/products/category","/wx/carousel/list").permitAll()
|
||||
// 临时放开权限校验,共开发测试使用
|
||||
// .antMatchers("/wx/**").permitAll()
|
||||
.antMatchers("/wx/payApi/**").permitAll()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest().authenticated();
|
||||
})
|
||||
// 添加Logout filter
|
||||
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
|
||||
// 添加JWT filter
|
||||
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
// 添加CORS filter
|
||||
.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
|
||||
.addFilterBefore(corsFilter, LogoutFilter.class)
|
||||
.build();
|
||||
.antMatchers("/login", "/register", "/captchaImage","/wx/user/mockLogin","/wx/user/login","/wxapp/userLogin/login").permitAll()
|
||||
// 静态资源,可匿名访问
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
// 微信静态资源访问不被拦截
|
||||
.antMatchers("/wx/static/**","/wx/payApi/").permitAll()
|
||||
// 部分接口开放,不受权限访问限制
|
||||
.antMatchers("/wx/area/**").permitAll()
|
||||
// 微信体验功能,部分接口权限放开
|
||||
// 首页查询商品查询,轮播图查询,类别查询,按类别查询商品接口
|
||||
.antMatchers("/wx/products/indexProducts","/wx/dict/type/product_category","/wx/products/category","/wx/carousel/list").permitAll()
|
||||
// 临时放开权限校验,共开发测试使用
|
||||
// .antMatchers("/wx/**").permitAll()
|
||||
.antMatchers("/wx/payApi/**").permitAll()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest().authenticated();
|
||||
// 添加Logout filter
|
||||
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
|
||||
// 添加JWT filter
|
||||
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,4 +149,11 @@ public class SecurityConfig
|
||||
{
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
// auth.inMemoryAuthentication().passwordEncoder(bCryptPasswordEncoder());
|
||||
//auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
|
||||
auth.authenticationProvider(clientLoginAuthProvider());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.zf.foodpurchase.framework.service;
|
||||
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
public interface ClientUserDetailsService {
|
||||
UserDetails loadUserByUsername(String username, String tenantId) throws UsernameNotFoundException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.zf.foodpurchase.framework.service.impl;
|
||||
|
||||
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysUser;
|
||||
import com.zf.foodpurchase.common.core.domain.model.LoginUser;
|
||||
import com.zf.foodpurchase.common.enums.UserStatus;
|
||||
import com.zf.foodpurchase.common.exception.ServiceException;
|
||||
import com.zf.foodpurchase.common.utils.StringUtils;
|
||||
import com.zf.foodpurchase.framework.web.service.SysPasswordService;
|
||||
import com.zf.foodpurchase.framework.web.service.SysPermissionService;
|
||||
import com.zf.foodpurchase.system.mapper.SysDeptMapper;
|
||||
import com.zf.foodpurchase.system.mapper.SysRoleDeptMapper;
|
||||
import com.zf.foodpurchase.system.mapper.SysUserMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.zf.foodpurchase.framework.service.ClientUserDetailsService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Service("clientUserDetailsService")
|
||||
public class ClientUserDetailsServiceImpl implements ClientUserDetailsService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ClientUserDetailsServiceImpl.class);
|
||||
|
||||
@Resource
|
||||
private SysUserMapper sysUserMapper;
|
||||
|
||||
@Autowired
|
||||
private SysPasswordService passwordService;
|
||||
|
||||
@Autowired
|
||||
private SysPermissionService permissionService;
|
||||
|
||||
@Autowired
|
||||
private SysRoleDeptMapper roleDeptMapper;
|
||||
|
||||
@Autowired
|
||||
private SysDeptMapper deptMapper;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username, String tenantId) throws UsernameNotFoundException {
|
||||
// 此处即可自定义查询用户
|
||||
SysUser user = sysUserMapper.selectUserByUserNameAndTenantId(username,tenantId);
|
||||
if (StringUtils.isNull(user))
|
||||
{
|
||||
log.info("登录用户:{} 不存在.", username);
|
||||
throw new ServiceException("登录用户:" + username + " 不存在");
|
||||
}
|
||||
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||
{
|
||||
log.info("登录用户:{} 已被删除.", username);
|
||||
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
|
||||
}
|
||||
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||
{
|
||||
log.info("登录用户:{} 已被停用.", username);
|
||||
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
|
||||
}
|
||||
|
||||
passwordService.validate(user);
|
||||
|
||||
return createLoginUser(user);
|
||||
}
|
||||
|
||||
public UserDetails createLoginUser(SysUser user)
|
||||
{
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.zf.foodpurchase.framework.web.service;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.zf.foodpurchase.common.constant.CacheConstants;
|
||||
import com.zf.foodpurchase.common.constant.Constants;
|
||||
import com.zf.foodpurchase.common.constant.UserConstants;
|
||||
import com.zf.foodpurchase.common.core.domain.AjaxResult;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysTenantVo;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysUser;
|
||||
import com.zf.foodpurchase.common.core.domain.model.LoginUser;
|
||||
import com.zf.foodpurchase.common.core.redis.RedisCache;
|
||||
@@ -12,10 +15,12 @@ import com.zf.foodpurchase.common.utils.DateUtils;
|
||||
import com.zf.foodpurchase.common.utils.MessageUtils;
|
||||
import com.zf.foodpurchase.common.utils.StringUtils;
|
||||
import com.zf.foodpurchase.common.utils.ip.IpUtils;
|
||||
import com.zf.foodpurchase.framework.config.CustomUsernamePasswordAuthenticationToken;
|
||||
import com.zf.foodpurchase.framework.manager.AsyncManager;
|
||||
import com.zf.foodpurchase.framework.manager.factory.AsyncFactory;
|
||||
import com.zf.foodpurchase.framework.security.context.AuthenticationContextHolder;
|
||||
import com.zf.foodpurchase.system.service.ISysConfigService;
|
||||
import com.zf.foodpurchase.system.service.ISysTenantService;
|
||||
import com.zf.foodpurchase.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -26,6 +31,9 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
@@ -39,7 +47,6 @@ public class SysLoginService
|
||||
private TokenService tokenService;
|
||||
|
||||
@Resource
|
||||
@Qualifier("authenticationManager")
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Autowired
|
||||
@@ -51,26 +58,39 @@ public class SysLoginService
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private ISysTenantService tenantService;
|
||||
|
||||
/**
|
||||
* 登录验证
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(String username, String password, String code, String uuid)
|
||||
public AjaxResult login(String tenantId, String username, String password)
|
||||
{
|
||||
// 验证码校验
|
||||
validateCaptcha(username, code, uuid);
|
||||
//validateCaptcha(username, code, uuid);
|
||||
// 登录前置校验
|
||||
loginPreCheck(username, password);
|
||||
//loginPreCheck(username, password);
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
return AjaxResult.error("请选择租户");
|
||||
}
|
||||
SysTenantVo tenant = tenantService.queryByTenantId(tenantId);
|
||||
if (ObjectUtil.isNull(tenant)) {
|
||||
return AjaxResult.error("租户不存在");
|
||||
} else if ("1".equals(tenant.getStatus())) {
|
||||
return AjaxResult.error("租户已停用");
|
||||
} else if (ObjectUtil.isNotNull(tenant.getExpireTime())
|
||||
&& new Date().after(tenant.getExpireTime())) {
|
||||
return AjaxResult.error("租户已过期");
|
||||
}
|
||||
// 用户验证
|
||||
Authentication authentication = null;
|
||||
try
|
||||
{
|
||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
|
||||
CustomUsernamePasswordAuthenticationToken authenticationToken = new CustomUsernamePasswordAuthenticationToken(username, password,tenantId);
|
||||
AuthenticationContextHolder.setContext(authenticationToken);
|
||||
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
||||
authentication = authenticationManager.authenticate(authenticationToken);
|
||||
@@ -96,7 +116,12 @@ public class SysLoginService
|
||||
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
||||
recordLoginInfo(loginUser.getUserId());
|
||||
// 生成token
|
||||
return tokenService.createToken(loginUser);
|
||||
String token = tokenService.createToken(loginUser);
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put(Constants.TOKEN, token);
|
||||
map.put("userId",loginUser.getUserId());
|
||||
return AjaxResult.success(map);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
package com.zf.foodpurchase.framework.web.service;
|
||||
|
||||
import com.zf.foodpurchase.common.constant.CacheConstants;
|
||||
import com.zf.foodpurchase.common.constant.Constants;
|
||||
import com.zf.foodpurchase.common.constant.UserConstants;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysUser;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.WxAppUserVO;
|
||||
import com.zf.foodpurchase.common.core.domain.model.LoginUser;
|
||||
import com.zf.foodpurchase.common.core.domain.model.WxAppLoginBody;
|
||||
import com.zf.foodpurchase.common.core.domain.model.WxAppLoginUser;
|
||||
import com.zf.foodpurchase.common.core.redis.RedisCache;
|
||||
import com.zf.foodpurchase.common.exception.ServiceException;
|
||||
import com.zf.foodpurchase.common.exception.user.*;
|
||||
import com.zf.foodpurchase.common.utils.DateUtils;
|
||||
import com.zf.foodpurchase.common.utils.MessageUtils;
|
||||
import com.zf.foodpurchase.common.utils.StringUtils;
|
||||
import com.zf.foodpurchase.common.utils.ip.IpUtils;
|
||||
import com.zf.foodpurchase.fdsafe.entity.WxAppUser;
|
||||
import com.zf.foodpurchase.fdsafe.service.IWxAppUserService;
|
||||
import com.zf.foodpurchase.framework.manager.AsyncManager;
|
||||
import com.zf.foodpurchase.framework.manager.factory.AsyncFactory;
|
||||
import com.zf.foodpurchase.framework.security.context.AuthenticationContextHolder;
|
||||
import com.zf.foodpurchase.system.service.ISysConfigService;
|
||||
import com.zf.foodpurchase.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public class WxAppLoginService
|
||||
{
|
||||
@Autowired
|
||||
private WxAppTokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("wxAppAuthenticationManager")
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Autowired
|
||||
private IWxAppUserService wxAppUserService;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
/**
|
||||
* 登录验证
|
||||
*
|
||||
* @param wxAppLoginBody 登录对象
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(WxAppLoginBody wxAppLoginBody)
|
||||
{
|
||||
String username = wxAppLoginBody.getUsername();
|
||||
String password = wxAppLoginBody.getPassword();
|
||||
// 验证码校验
|
||||
// validateCaptcha(username, code, uuid);
|
||||
// 登录前置校验
|
||||
loginPreCheck(username, password);
|
||||
// 用户验证
|
||||
Authentication authentication = null;
|
||||
try
|
||||
{
|
||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
|
||||
AuthenticationContextHolder.setContext(authenticationToken);
|
||||
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
||||
authentication = authenticationManager.authenticate(authenticationToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof BadCredentialsException)
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||
throw new UserPasswordNotMatchException();
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
AuthenticationContextHolder.clearContext();
|
||||
}
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
|
||||
WxAppLoginUser loginUser = (WxAppLoginUser) authentication.getPrincipal();
|
||||
recordLoginInfo(loginUser.getUserId());
|
||||
// 生成token
|
||||
return tokenService.createWxAppToken(loginUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
* @return 结果
|
||||
*/
|
||||
public void validateCaptcha(String username, String code, String uuid)
|
||||
{
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
if (captchaEnabled)
|
||||
{
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
|
||||
String captcha = redisCache.getCacheObject(verifyKey);
|
||||
if (captcha == null)
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
redisCache.deleteObject(verifyKey);
|
||||
if (!code.equalsIgnoreCase(captcha))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录前置校验
|
||||
* @param username 用户名
|
||||
* @param password 用户密码
|
||||
*/
|
||||
public void loginPreCheck(String username, String password)
|
||||
{
|
||||
// 用户名或密码为空 错误
|
||||
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
|
||||
throw new UserNotExistsException();
|
||||
}
|
||||
// 密码如果不在指定范围内 错误
|
||||
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||
throw new UserPasswordNotMatchException();
|
||||
}
|
||||
// 用户名不在指定范围内 错误
|
||||
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|
||||
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||
throw new UserPasswordNotMatchException();
|
||||
}
|
||||
// IP黑名单校验
|
||||
String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
|
||||
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
|
||||
throw new BlackListException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
public void recordLoginInfo(Long userId)
|
||||
{
|
||||
WxAppUser user = new WxAppUser();
|
||||
user.setId(userId);
|
||||
user.setLoginTime(DateUtils.getNowDate());
|
||||
user.setLoginIp(IpUtils.getIpAddr());
|
||||
user.setUpdateTime(DateUtils.getNowDate());
|
||||
wxAppUserService.updateById(user);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.zf.foodpurchase.fdsafe.vo;
|
||||
import com.zf.foodpurchase.common.valigroud.UpdateGroup;
|
||||
import com.zf.foodpurchase.common.vo.CommonVO;
|
||||
import lombok.Data;
|
||||
import org.w3c.dom.stylesheets.LinkStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.zf.foodpurchase.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.zf.foodpurchase.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 租户对象 sys_tenant
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_tenant")
|
||||
public class SysTenant extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
private String contactUserName;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String contactPhone;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 统一社会信用代码
|
||||
*/
|
||||
private String licenseNumber;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 企业简介
|
||||
*/
|
||||
private String intro;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 租户套餐编号
|
||||
*/
|
||||
private Long packageId;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 用户数量(-1不限制)
|
||||
*/
|
||||
private Long accountCount;
|
||||
|
||||
/**
|
||||
* 租户状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
private Long createDept;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.zf.foodpurchase.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.zf.foodpurchase.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 租户套餐对象 sys_tenant_package
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_tenant_package")
|
||||
public class SysTenantPackage extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户套餐id
|
||||
*/
|
||||
@TableId(value = "package_id")
|
||||
private Long packageId;
|
||||
|
||||
/**
|
||||
* 套餐名称
|
||||
*/
|
||||
private String packageName;
|
||||
|
||||
/**
|
||||
* 关联菜单id
|
||||
*/
|
||||
private String menuIds;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)
|
||||
*/
|
||||
private Boolean menuCheckStrictly;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
private Long createDept;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private String updateBy;
|
||||
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.zf.foodpurchase.system.domain.vo;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 租户套餐视图对象 sys_tenant_package
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Data
|
||||
public class SysTenantPackageVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户套餐id
|
||||
*/
|
||||
private Long packageId;
|
||||
|
||||
/**
|
||||
* 套餐名称
|
||||
*/
|
||||
private String packageName;
|
||||
|
||||
/**
|
||||
* 关联菜单id
|
||||
*/
|
||||
private String menuIds;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 菜单树选择项是否关联显示
|
||||
*/
|
||||
private Boolean menuCheckStrictly;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
}
|
||||
@@ -115,4 +115,12 @@ public interface SysDeptMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteDeptById(Long deptId);
|
||||
|
||||
public int updateDeptByTenantId(@Param("dept") SysDept dept, @Param("tenantId") String tenantId);
|
||||
|
||||
public List<SysDept> selectByTenantId(@Param("tenantId") String tenantId);
|
||||
|
||||
public void updateTenantId(@Param("deptIds") List<Long> deptIds, @Param("tenantId") String tenantId);
|
||||
|
||||
public List<Long> selectAllZSByDeptId(Long deptId);
|
||||
}
|
||||
|
||||
@@ -104,4 +104,6 @@ public interface SysRoleMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteRoleByIds(Long[] roleIds);
|
||||
|
||||
public List<SysRole> selectRolesByTenantId(String tenantId);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.zf.foodpurchase.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.zf.foodpurchase.system.domain.SysRoleMenu;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 角色与菜单关联表 数据层
|
||||
@@ -41,4 +42,6 @@ public interface SysRoleMenuMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public int batchRoleMenu(List<SysRoleMenu> roleMenuList);
|
||||
|
||||
public int deleteRoleMenuForSync(@Param("roleIds") List<Long> roleIds, @Param("menuIds") List<Long> menuIds);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.zf.foodpurchase.system.mapper;
|
||||
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysTenantBo;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysTenantVo;
|
||||
import com.zf.foodpurchase.system.domain.SysTenant;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysTenantMapper {
|
||||
|
||||
public SysTenantVo queryById(Long id);
|
||||
|
||||
public List<SysTenantVo> queryByCondition(SysTenantBo bo);
|
||||
|
||||
public int deleteByIds(@Param("ids") List<Long> ids);
|
||||
|
||||
public int updateById(SysTenant sysTenant);
|
||||
|
||||
public int insert(SysTenant sysTenant);
|
||||
|
||||
public SysTenantVo queryByTenantId(String tenantId);
|
||||
|
||||
public List<String> selectObjs();
|
||||
|
||||
public List<SysTenantVo> queryByPackageIds(@Param("packageIds") List<Long> packageIds);
|
||||
|
||||
public List<SysTenantVo> queryByCompanyName(String companyName);
|
||||
|
||||
public List<SysTenantVo> queryByPhone(String phone);
|
||||
|
||||
public List<SysTenantVo> queryByTenantIds(@Param("tenantIds") List<String> tenantIds);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.zf.foodpurchase.system.mapper;
|
||||
|
||||
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysTenantPackageBo;
|
||||
import com.zf.foodpurchase.system.domain.SysTenantPackage;
|
||||
import com.zf.foodpurchase.system.domain.vo.SysTenantPackageVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysTenantPackageMapper {
|
||||
|
||||
public SysTenantPackageVo selectById(Long packageId);
|
||||
|
||||
public List<SysTenantPackageVo> selectList(SysTenantPackageBo sysTenantPackageBo);
|
||||
|
||||
public int insert(SysTenantPackage sysTenantPackage);
|
||||
|
||||
public int update(SysTenantPackage sysTenantPackage);
|
||||
|
||||
public int deleteByIds(@Param("packageIds") List<Long> packageIds);
|
||||
}
|
||||
@@ -124,4 +124,14 @@ public interface SysUserMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public SysUser checkEmailUnique(String email);
|
||||
|
||||
|
||||
int unableUser(@Param("userIds") List<Long> userIds,@Param("statusChar") String statusChar);
|
||||
|
||||
List<Long> selectUserIdsByTenantId(@Param("tenantId") String tenantId);
|
||||
|
||||
int updateTenantIdOfUsers(@Param("deptIds") List<Long> deptIds,@Param("tenantId") String tenantId);
|
||||
|
||||
SysUser selectUserByUserNameAndTenantId(@Param("userName") String userName,@Param("tenantId") String tenantId);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.zf.foodpurchase.system.service;
|
||||
|
||||
|
||||
|
||||
import com.zf.foodpurchase.common.core.domain.AjaxResult;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysTenantBo;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.SysTenantVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 租户Service接口
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
public interface ISysTenantService {
|
||||
|
||||
/**
|
||||
* 查询租户
|
||||
*/
|
||||
SysTenantVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 基于租户ID查询租户
|
||||
*/
|
||||
SysTenantVo queryByTenantId(String tenantId);
|
||||
|
||||
/**
|
||||
* 查询租户列表
|
||||
*/
|
||||
AjaxResult queryPageList(SysTenantBo bo, Integer page, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 查询租户列表
|
||||
*/
|
||||
AjaxResult queryList(SysTenantBo bo);
|
||||
|
||||
/**
|
||||
* 新增租户
|
||||
*/
|
||||
Boolean insertByBo(SysTenantBo bo);
|
||||
|
||||
/**
|
||||
* 修改租户
|
||||
*/
|
||||
Boolean updateByBo(SysTenantBo bo);
|
||||
|
||||
|
||||
/**
|
||||
* 校验租户是否允许操作
|
||||
*/
|
||||
void checkTenantAllowed(String tenantId);
|
||||
|
||||
/**
|
||||
* 校验并批量删除租户信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(List<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 校验企业名称是否唯一
|
||||
*/
|
||||
boolean checkCompanyNameUnique(SysTenantBo bo);
|
||||
|
||||
/**
|
||||
* 校验联系方式是否唯一
|
||||
*/
|
||||
boolean checkPhoneUnique(SysTenantBo bo);
|
||||
|
||||
/**
|
||||
* 校验用户名是否唯一
|
||||
*/
|
||||
boolean checkUsername(SysTenantBo bo);
|
||||
|
||||
/**
|
||||
* 校验有效期
|
||||
*/
|
||||
boolean checkExpireTime(String tenantId);
|
||||
|
||||
/**
|
||||
* 修改租户状态
|
||||
*/
|
||||
int updateTenantStatus(SysTenantBo bo);
|
||||
|
||||
Boolean deptToTenant(SysTenantBo bo);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
package com.zf.foodpurchase.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.zf.foodpurchase.common.constant.TenantConstants;
|
||||
import com.zf.foodpurchase.common.core.domain.AjaxResult;
|
||||
import com.zf.foodpurchase.common.core.domain.entity.*;
|
||||
import com.zf.foodpurchase.common.core.domain.model.LoginUser;
|
||||
import com.zf.foodpurchase.common.exception.ServiceException;
|
||||
import com.zf.foodpurchase.common.utils.PageResult;
|
||||
import com.zf.foodpurchase.common.utils.SecurityUtils;
|
||||
import com.zf.foodpurchase.common.utils.StringUtils;
|
||||
import com.zf.foodpurchase.common.utils.spring.SpringUtils;
|
||||
import com.zf.foodpurchase.system.domain.SysRoleDept;
|
||||
import com.zf.foodpurchase.system.domain.SysRoleMenu;
|
||||
import com.zf.foodpurchase.system.domain.SysTenant;
|
||||
import com.zf.foodpurchase.system.domain.SysUserRole;
|
||||
import com.zf.foodpurchase.system.domain.vo.SysTenantPackageVo;
|
||||
import com.zf.foodpurchase.system.mapper.*;
|
||||
import com.zf.foodpurchase.system.service.ISysTenantService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 租户Service业务层处理
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysTenantServiceImpl implements ISysTenantService {
|
||||
|
||||
private final SysTenantMapper baseMapper;
|
||||
private final SysTenantPackageMapper tenantPackageMapper;
|
||||
private final SysUserMapper userMapper;
|
||||
private final SysDeptMapper deptMapper;
|
||||
private final SysRoleMapper roleMapper;
|
||||
private final SysRoleMenuMapper roleMenuMapper;
|
||||
private final SysRoleDeptMapper roleDeptMapper;
|
||||
private final SysUserRoleMapper userRoleMapper;
|
||||
private final SysTenantMapper sysTenantMapper;
|
||||
private final SysUserMapper sysUserMapper;
|
||||
private final SysDeptMapper sysDeptMapper;
|
||||
|
||||
/**
|
||||
* 查询租户
|
||||
*/
|
||||
@Override
|
||||
public SysTenantVo queryById(Long id) {
|
||||
SysTenantVo sysTenantVo = baseMapper.queryById(id);
|
||||
return sysTenantVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于租户ID查询租户
|
||||
*/
|
||||
@Override
|
||||
public SysTenantVo queryByTenantId(String tenantId) {
|
||||
return baseMapper.queryByTenantId(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询租户列表
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult queryPageList(SysTenantBo bo, Integer page, Integer pageSize) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
List<SysTenantVo> sysTenantVos = baseMapper.queryByCondition(bo);
|
||||
PageInfo<SysTenantVo> pageInfo = new PageInfo<>(sysTenantVos);
|
||||
PageResult result = new PageResult();
|
||||
result.setPageIndex(page);
|
||||
result.setPages(pageInfo.getPages());
|
||||
result.setTotles(pageInfo.getTotal());
|
||||
result.setResult(sysTenantVos);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询租户列表
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult queryList(SysTenantBo bo) {
|
||||
List<SysTenantVo> sysTenantVos = baseMapper.queryByCondition(bo);
|
||||
return AjaxResult.success(sysTenantVos);
|
||||
}
|
||||
/**
|
||||
* 新增租户
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(SysTenantBo bo) {
|
||||
Date date = new Date();
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getLoginUser();
|
||||
SysTenant add = BeanUtil.toBean(bo, SysTenant.class);
|
||||
// 获取所有租户编号
|
||||
List<String> tenantIds = baseMapper.selectObjs();
|
||||
String tenantId = generateTenantId(tenantIds);
|
||||
add.setTenantId(tenantId);
|
||||
add.setCreateDept(bo.getDeptId());
|
||||
add.setCreateTime(new Date());
|
||||
add.setCreateBy(loginUser.getUserId()+"");
|
||||
add.setStatus("0");
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (!flag) {
|
||||
throw new ServiceException("创建租户失败");
|
||||
}
|
||||
bo.setId(add.getId());
|
||||
|
||||
// 根据套餐创建角色
|
||||
Long roleId = createTenantRole(tenantId, bo.getPackageId(),bo.getCompanyName());
|
||||
|
||||
// 创建部门: 公司名是部门名称
|
||||
SysDept dept = new SysDept();
|
||||
dept.setTenantId(tenantId);
|
||||
dept.setDeptName(bo.getCompanyName());
|
||||
if(!ObjectUtil.isEmpty(bo.getDeptId())){
|
||||
dept.setParentId(bo.getDeptId());
|
||||
SysDept parentDept = deptMapper.selectDeptById(bo.getDeptId());
|
||||
String ancestors = parentDept.getAncestors()+","+bo.getDeptId();
|
||||
dept.setAncestors(ancestors);
|
||||
}else{
|
||||
dept.setParentId(0L);
|
||||
dept.setAncestors("0");
|
||||
}
|
||||
dept.setIsTenant("1");
|
||||
dept.setCreateTime(date);
|
||||
dept.setStatus("0");
|
||||
dept.setDelFlag("0");
|
||||
deptMapper.insertDept(dept);
|
||||
Long deptId = dept.getDeptId();
|
||||
// 角色和部门关联表
|
||||
SysRoleDept roleDept = new SysRoleDept();
|
||||
roleDept.setRoleId(roleId);
|
||||
roleDept.setDeptId(deptId);
|
||||
roleDeptMapper.batchRoleDept(Arrays.asList(roleDept));
|
||||
|
||||
// 创建系统用户
|
||||
SysUser user = new SysUser();
|
||||
user.setTenantId(tenantId);
|
||||
user.setUserName(bo.getUsername());
|
||||
user.setNickName(bo.getUsername());
|
||||
user.setPassword(BCrypt.hashpw(bo.getPassword()));
|
||||
user.setDeptId((long) deptId);
|
||||
user.setCreateTime(date);
|
||||
user.setUpdateTime(date);
|
||||
user.setDelFlag("0");
|
||||
user.setPhonenumber(bo.getContactPhone());
|
||||
user.setStatus("0");
|
||||
userMapper.insertUser(user);
|
||||
//新增系统用户后,默认当前用户为部门的负责人
|
||||
SysDept sd = new SysDept();
|
||||
sd.setLeader(user.getUserName().toString());
|
||||
sd.setDeptId(deptId);
|
||||
deptMapper.updateDept(sd);
|
||||
|
||||
// 用户和角色关联表
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setUserId(user.getUserId());
|
||||
userRole.setRoleId(roleId);
|
||||
userRoleMapper.batchUserRole(Arrays.asList(userRole));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成租户id
|
||||
*
|
||||
* @param tenantIds 已有租户id列表
|
||||
* @return 租户id
|
||||
*/
|
||||
private String generateTenantId(List<String> tenantIds) {
|
||||
// 随机生成6位
|
||||
String numbers = RandomUtil.randomNumbers(6);
|
||||
// 判断是否存在,如果存在则重新生成
|
||||
if (tenantIds.contains(numbers)) {
|
||||
return generateTenantId(tenantIds);
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据租户菜单创建租户角色
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param packageId 租户套餐id
|
||||
* @return 角色id
|
||||
*/
|
||||
private Long createTenantRole(String tenantId, Long packageId, String companyName) {
|
||||
// 获取租户套餐
|
||||
SysTenantPackageVo tenantPackageVo = tenantPackageMapper.selectById(packageId);
|
||||
if (ObjectUtil.isNull(tenantPackageVo)) {
|
||||
throw new ServiceException("套餐不存在");
|
||||
}
|
||||
// 获取套餐菜单id
|
||||
List<Long> menuIds = StrUtil.split(tenantPackageVo.getMenuIds(), ',')
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(Convert::toLong)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 创建角色
|
||||
SysRole role = new SysRole();
|
||||
role.setTenantId(tenantId);
|
||||
role.setRoleName(companyName+ TenantConstants.TENANT_ADMIN_ROLE_NAME);
|
||||
role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY + "_" + tenantId);
|
||||
role.setRoleSort(1);
|
||||
role.setStatus("0");
|
||||
roleMapper.insertRole(role);
|
||||
Long roleId = role.getRoleId();
|
||||
|
||||
// 创建角色菜单
|
||||
List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
|
||||
menuIds.forEach(menuId -> {
|
||||
SysRoleMenu roleMenu = new SysRoleMenu();
|
||||
roleMenu.setRoleId(roleId);
|
||||
roleMenu.setMenuId(menuId);
|
||||
roleMenus.add(roleMenu);
|
||||
});
|
||||
if(roleMenus.size() > 0) {
|
||||
roleMenuMapper.batchRoleMenu(roleMenus);
|
||||
}
|
||||
|
||||
return roleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改租户
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(SysTenantBo bo) {
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getLoginUser();
|
||||
SysTenant tenant = new SysTenant();
|
||||
BeanUtil.copyProperties(bo, tenant);
|
||||
|
||||
if(!ObjectUtil.isEmpty(bo.getDeptId())){ //非租户部门
|
||||
SysDept currentDept = new SysDept();
|
||||
currentDept.setParentId(bo.getDeptId());
|
||||
SysDept parentDept = deptMapper.selectDeptById(bo.getDeptId());
|
||||
String ancestors = parentDept.getAncestors()+","+bo.getDeptId();
|
||||
currentDept.setAncestors(ancestors);
|
||||
currentDept.setDeptName(bo.getCompanyName());
|
||||
deptMapper.updateDeptByTenantId(currentDept, tenant.getTenantId());
|
||||
}else{
|
||||
List<SysDept> currentDepts = deptMapper.selectByTenantId(tenant.getTenantId());
|
||||
SysDept tenantDept = currentDepts.stream().filter(f -> StringUtils.equals(f.getLeader(),"admin")).findFirst().orElse(null);
|
||||
if(!ObjectUtil.isNull(tenantDept)){
|
||||
tenantDept.setDeptName(bo.getCompanyName());
|
||||
deptMapper.updateDept(tenantDept);
|
||||
}
|
||||
}
|
||||
SysTenantVo original = sysTenantMapper.queryById(bo.getId());
|
||||
if(!ObjectUtil.equal(original.getPackageId(), bo.getPackageId())){
|
||||
syncTenantPackage(bo.getTenantId(),bo.getPackageId());
|
||||
}
|
||||
if(!ObjectUtil.equal(original.getCreateDept(), bo.getDeptId())){
|
||||
tenant.setCreateDept(bo.getDeptId());
|
||||
}
|
||||
tenant.setCreateDept(bo.getDeptId());
|
||||
tenant.setUpdateBy(loginUser.getUserId()+"");
|
||||
return baseMapper.updateById(tenant) > 0;
|
||||
}
|
||||
|
||||
public Boolean syncTenantPackage(String tenantId, Long packageId) {
|
||||
SysTenantPackageVo tenantPackageVO = tenantPackageMapper.selectById(packageId);
|
||||
List<SysRole> roles = roleMapper.selectRolesByTenantId(tenantId);
|
||||
List<Long> roleIds = new ArrayList<>(roles.size() - 1);
|
||||
List<Long> menuIds = StringUtils.commaStrToLongList(tenantPackageVO.getMenuIds());
|
||||
roles.forEach(item -> {
|
||||
if (item.getRoleKey().contains(TenantConstants.TENANT_ADMIN_ROLE_KEY)) {
|
||||
List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
|
||||
menuIds.forEach(menuId -> {
|
||||
SysRoleMenu roleMenu = new SysRoleMenu();
|
||||
roleMenu.setRoleId(item.getRoleId());
|
||||
roleMenu.setMenuId(menuId);
|
||||
roleMenus.add(roleMenu);
|
||||
});
|
||||
roleMenuMapper.deleteRoleMenuByRoleId(item.getRoleId());
|
||||
roleMenuMapper.batchRoleMenu(roleMenus);
|
||||
} else {
|
||||
roleIds.add(item.getRoleId());
|
||||
}
|
||||
});
|
||||
if (!roleIds.isEmpty()) {
|
||||
roleMenuMapper.deleteRoleMenuForSync(roleIds, menuIds);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验租户是否允许操作
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
*/
|
||||
@Override
|
||||
public void checkTenantAllowed(String tenantId) {
|
||||
if (ObjectUtil.isNotNull(tenantId) && TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
|
||||
throw new ServiceException("不允许操作管理租户");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除租户
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(List<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// 做一些业务上的校验,判断是否需要校验
|
||||
if (ids.contains(TenantConstants.SUPER_ADMIN_ID)) {
|
||||
throw new ServiceException("超管租户不能删除");
|
||||
}
|
||||
}
|
||||
boolean i = baseMapper.deleteByIds(ids)>0;
|
||||
List<SysDept> sysDepts = new ArrayList<>();
|
||||
for(Long id:ids){
|
||||
SysTenantVo sysTenantVo = sysTenantMapper.queryById(id);
|
||||
if(ObjectUtil.isNotNull(sysTenantVo)){
|
||||
List<SysDept> depts = sysDeptMapper.selectByTenantId(sysTenantVo.getTenantId());
|
||||
sysDepts.addAll(depts);
|
||||
}
|
||||
}
|
||||
for(SysDept s:sysDepts){
|
||||
s.setIsTenant("0");
|
||||
sysDeptMapper.updateDept(s);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验企业名称是否唯一
|
||||
*/
|
||||
@Override
|
||||
public boolean checkCompanyNameUnique(SysTenantBo bo) {
|
||||
List<SysTenantVo> list = baseMapper.queryByCompanyName(bo.getCompanyName());
|
||||
if(StringUtils.isEmpty(bo.getTenantId())){ // 新增
|
||||
if(list.size()>0){
|
||||
return false;
|
||||
}
|
||||
}else{ //修改
|
||||
SysTenantVo sysTenantVo = list.stream().filter(item->!bo.getTenantId().equals(item.getTenantId())).findFirst().orElse(null);
|
||||
if(ObjectUtil.isNotEmpty(sysTenantVo)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验联系方式是否唯一
|
||||
*/
|
||||
@Override
|
||||
public boolean checkPhoneUnique(SysTenantBo bo) {
|
||||
List<SysTenantVo> list = baseMapper.queryByPhone(bo.getContactPhone());
|
||||
if(StringUtils.isEmpty(bo.getTenantId())){ // 新增
|
||||
if(list.size()>0){
|
||||
return false;
|
||||
}
|
||||
}else{ //修改
|
||||
SysTenantVo sysTenantVo = list.stream().filter(item->!bo.getTenantId().equals(item.getTenantId())).findFirst().orElse(null);
|
||||
if(ObjectUtil.isNotEmpty(sysTenantVo)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkUsername(SysTenantBo bo) {
|
||||
SysUser info = userMapper.checkUserNameUnique(bo.getUsername());
|
||||
if(StringUtils.isEmpty(bo.getTenantId())){
|
||||
if(ObjectUtil.isNotNull(info)){
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
if(ObjectUtil.isNotNull(info)){
|
||||
if(StringUtils.equals(info.getTenantId(),bo.getTenantId())){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验有效期
|
||||
*/
|
||||
@Override
|
||||
public boolean checkExpireTime(String tenantId) {
|
||||
SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId);
|
||||
// 如果未设置过期时间代表不限制
|
||||
if (ObjectUtil.isNull(tenant.getExpireTime())) {
|
||||
return true;
|
||||
}
|
||||
// 如果当前时间在过期时间之前则通过
|
||||
return new Date().before(tenant.getExpireTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateTenantStatus(SysTenantBo bo) {
|
||||
SysTenant tenant = new SysTenant();
|
||||
tenant.setId(bo.getId());
|
||||
tenant.setStatus(bo.getStatus());
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getLoginUser();
|
||||
Long userId =loginUser.getUserId();
|
||||
SysTenantVo sysTenantVo = baseMapper.queryById(bo.getId());
|
||||
SysDept sysDept = new SysDept();
|
||||
sysDept.setUpdateBy(userId+"");
|
||||
sysDept.setStatus(bo.getStatus());
|
||||
deptMapper.updateDeptByTenantId(sysDept,sysTenantVo.getTenantId());
|
||||
List<Long> userIds = sysUserMapper.selectUserIdsByTenantId(sysTenantVo.getTenantId());
|
||||
if(CollectionUtil.isNotEmpty(userIds)){
|
||||
sysUserMapper.unableUser(userIds,bo.getStatus());
|
||||
}
|
||||
return baseMapper.updateById(tenant);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deptToTenant(SysTenantBo bo) {
|
||||
Long deptId = bo.getDeptId();
|
||||
Date date = new Date();
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getLoginUser();
|
||||
SysTenant add = BeanUtil.toBean(bo, SysTenant.class);
|
||||
// 获取所有租户编号
|
||||
List<String> tenantIds = baseMapper.selectObjs();
|
||||
String tenantId = generateTenantId(tenantIds);
|
||||
add.setTenantId(tenantId);
|
||||
add.setCreateDept(deptId);
|
||||
add.setCreateTime(date);
|
||||
add.setCreateBy(loginUser.getUserId()+"");
|
||||
add.setStatus("0");
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (!flag) {
|
||||
throw new ServiceException("创建租户失败");
|
||||
}
|
||||
// 根据套餐创建角色
|
||||
Long roleId = createTenantRole(tenantId, bo.getPackageId(),bo.getCompanyName());
|
||||
|
||||
// 角色和部门关联表
|
||||
SysRoleDept roleDept = new SysRoleDept();
|
||||
roleDept.setRoleId(roleId);
|
||||
roleDept.setDeptId(deptId);
|
||||
roleDeptMapper.batchRoleDept(Arrays.asList(roleDept));
|
||||
|
||||
// 创建系统用户
|
||||
SysUser user = new SysUser();
|
||||
user.setTenantId(tenantId);
|
||||
user.setUserName("admin");
|
||||
user.setNickName("admin");
|
||||
user.setPassword(BCrypt.hashpw("123456"));
|
||||
user.setDeptId((long) deptId);
|
||||
user.setCreateTime(date);
|
||||
user.setUpdateTime(date);
|
||||
user.setDelFlag("0");
|
||||
user.setStatus("0");
|
||||
userMapper.insertUser(user);
|
||||
//新增系统用户后,默认当前用户为部门的负责人
|
||||
SysDept sd = new SysDept();
|
||||
sd.setLeader(user.getUserName().toString());
|
||||
sd.setDeptId(deptId);
|
||||
sd.setIsTenant("1");
|
||||
sd.setTenantId(tenantId);
|
||||
deptMapper.updateDept(sd);
|
||||
|
||||
List<Long> deptIds = deptMapper.selectAllZSByDeptId(deptId);
|
||||
deptIds.add(deptId);
|
||||
//更新当前升级为租户的部门下属所有子孙节点的租户ID
|
||||
deptMapper.updateTenantId(deptIds,tenantId);
|
||||
//更新当前升级为租户的部门下属所有子孙节点的用户租户ID
|
||||
userMapper.updateTenantIdOfUsers(deptIds,tenantId);
|
||||
// 用户和角色关联表
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setUserId(user.getUserId());
|
||||
userRole.setRoleId(roleId);
|
||||
userRoleMapper.batchUserRole(Arrays.asList(userRole));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
149
fp-system/src/main/resources/mapper/SysTenantMapper.xml
Normal file
149
fp-system/src/main/resources/mapper/SysTenantMapper.xml
Normal file
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
|
||||
<mapper namespace="com.zf.foodpurchase.system.mapper.SysTenantMapper">
|
||||
<sql id="selectSysTenantVo">
|
||||
select id,tenant_id tenantId,contact_user_name contactUserName,contact_phone contactPhone,company_name companyName,license_number licenseNumber,
|
||||
address,intro,domain,remark,status,
|
||||
package_id packageId,expire_time expireTime,account_count accountCount,del_flag delFlag,create_dept createDept,create_by createBy,
|
||||
create_time createTime,update_by updateBy,update_time updateTime from sys_tenant
|
||||
</sql>
|
||||
|
||||
<select id="queryById" resultType="SysTenantVo">
|
||||
select id,st.tenant_id tenantId,contact_user_name contactUserName,contact_phone contactPhone,company_name companyName,license_number licenseNumber,
|
||||
address,intro,domain,remark,st.status,st.create_dept deptId,
|
||||
package_id packageId,expire_time expireTime,account_count accountCount,st.del_flag delFlag,create_dept createDept,st.create_by createBy,
|
||||
st.create_time createTime,st.update_by updateBy,st.update_time updateTime from sys_tenant st
|
||||
WHERE st.del_flag = '0' and st.id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="queryByCondition" parameterType="SysTenantBo" resultType="SysTenantVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where del_flag = '0'
|
||||
<if test="tenantId != null and tenantId != ''">
|
||||
AND tenant_id like concat('%', #{tenantId}, '%')
|
||||
</if>
|
||||
<if test="contactUserName != null and contactUserName != ''">
|
||||
AND contact_user_name like concat('%', #{contactUserName}, '%')
|
||||
</if>
|
||||
<if test="contactPhone != null and contactPhone != ''">
|
||||
AND contact_phone like concat('%', #{contactPhone}, '%')
|
||||
</if>
|
||||
<if test="companyName != null and companyName != ''">
|
||||
AND company_name like concat('%', #{companyName}, '%')
|
||||
</if>
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<select id="queryByCompanyName" parameterType="String" resultType="SysTenantVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where del_flag = '0' AND company_name = #{companyName}
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<select id="queryByPhone" parameterType="String" resultType="SysTenantVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where del_flag = '0' AND contact_phone = #{phone}
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<select id="queryByTenantId" parameterType="String" resultType="SysTenantVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where del_flag = '0' AND tenant_id = #{tenantId}
|
||||
</select>
|
||||
|
||||
<select id="queryByTenantIds" parameterType="String" resultType="SysTenantVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where del_flag = '0' AND tenant_id in
|
||||
<foreach collection="tenantIds" item="tenantId" open="(" separator="," close=")">
|
||||
#{tenantId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<delete id="deleteByIds" parameterType="Long">
|
||||
update sys_tenant set del_flag = '1' where id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="updateById" parameterType="SysTenant">
|
||||
update sys_tenant
|
||||
<set>
|
||||
<if test="companyName != null and companyName != ''">company_name = #{companyName},</if>
|
||||
<if test="contactUserName != null and contactUserName != ''">contact_user_name = #{contactUserName},</if>
|
||||
<if test="contactPhone != null and contactPhone != ''">contact_phone = #{contactPhone},</if>
|
||||
<if test="expireTime != null">expire_time = #{expireTime},</if>
|
||||
<if test="accountCount != null">account_count = #{accountCount},</if>
|
||||
<if test="domain != null and domain != ''">domain = #{domain},</if>
|
||||
<if test="address != null and address != ''">address = #{address},</if>
|
||||
<if test="licenseNumber != null">license_number = #{licenseNumber},</if>
|
||||
<if test="intro != null and intro != ''">intro = #{intro},</if>
|
||||
<if test="remark != null and remark != ''">remark = #{remark},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="createDept != null and createDept != ''">create_dept = #{createDept},</if>
|
||||
<if test="packageId != null">package_id = #{packageId},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
<insert id="insert" parameterType="SysTenant">
|
||||
INSERT INTO sys_tenant
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="tenantId != null">tenant_id,</if>
|
||||
<if test="contactUserName != null">contact_user_name,</if>
|
||||
<if test="contactPhone != null">contact_phone,</if>
|
||||
<if test="companyName != null">company_name,</if>
|
||||
<if test="licenseNumber != null">license_number,</if>
|
||||
<if test="address != null">address,</if>
|
||||
<if test="intro != null">intro,</if>
|
||||
<if test="domain != null">domain,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="packageId != null">package_id,</if>
|
||||
<if test="expireTime != null">expire_time,</if>
|
||||
<if test="accountCount != null">account_count,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="createDept != null">create_dept,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
</trim>
|
||||
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
|
||||
<if test="tenantId != null">#{tenantId},</if>
|
||||
<if test="contactUserName != null">#{contactUserName},</if>
|
||||
<if test="contactPhone != null">#{contactPhone},</if>
|
||||
<if test="companyName != null">#{companyName},</if>
|
||||
<if test="licenseNumber != null">#{licenseNumber},</if>
|
||||
<if test="address != null">#{address},</if>
|
||||
<if test="intro != null">#{intro},</if>
|
||||
<if test="domain != null">#{domain},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="packageId != null">#{packageId},</if>
|
||||
<if test="expireTime != null">#{expireTime},</if>
|
||||
<if test="accountCount != null">#{accountCount},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="createDept != null">#{createDept},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="selectObjs" resultType="String">
|
||||
select tenant_id tenantId from sys_tenant where del_flag = '0'
|
||||
</select>
|
||||
<select id="queryByPackageIds" resultType="SysTenantVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
WHERE del_flag = '0' and package_id in
|
||||
<foreach collection="packageIds" item="packageId" open="(" separator="," close=")">
|
||||
#{packageId}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
|
||||
<mapper namespace="com.zf.foodpurchase.system.mapper.SysTenantPackageMapper">
|
||||
<sql id="selectSysTenantVo">
|
||||
select package_id packageId,package_name packageName,menu_ids menuIds,remark,
|
||||
menu_check_strictly menuCheckStrictly,status,del_flag delFlag,create_dept createDept,create_by createBy,create_time createTime,
|
||||
update_by updateBy,update_time updateTime from sys_tenant_package
|
||||
</sql>
|
||||
<select id="selectById" resultType="SysTenantPackageVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where package_id=#{packageId} and del_flag = '0' limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectList" parameterType="SysTenantPackageBo" resultType="SysTenantPackageVo">
|
||||
<include refid="selectSysTenantVo"/>
|
||||
where del_flag = '0'
|
||||
<if test="packageName != null">
|
||||
AND package_name like concat('%',#{packageName},'%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<delete id="deleteByIds" parameterType="Long">
|
||||
update sys_tenant_package set del_flag = '1' where package_id in
|
||||
<foreach collection="packageIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="update" parameterType="SysTenantPackage">
|
||||
update sys_tenant_package
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="packageName != null">package_name = #{packageName},</if>
|
||||
<if test="menuIds != null">menu_ids = #{menuIds},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="menuCheckStrictly != null">menu_check_strictly = #{menuCheckStrictly},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
<if test="createDept != null">create_dept = #{createDept},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
</trim>
|
||||
WHERE package_id = #{packageId}
|
||||
</update>
|
||||
<insert id="insert" parameterType="SysTenantPackage">
|
||||
INSERT INTO sys_tenant_package
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="packageName != null">package_name,</if>
|
||||
<if test="menuIds != null">menu_ids,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="menuCheckStrictly != null">menu_check_strictly,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="createDept != null">create_dept,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
</trim>
|
||||
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
|
||||
<if test="packageName != null">#{packageName},</if>
|
||||
<if test="menuIds != null">#{menuIds},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="menuCheckStrictly != null">#{menuCheckStrictly},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="createDept != null">#{createDept},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
</mapper>
|
||||
@@ -6,6 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<resultMap type="SysRole" id="SysRoleResult">
|
||||
<id property="roleId" column="role_id" />
|
||||
<id property="tenantId" column="tenant_id" />
|
||||
<result property="roleName" column="role_name" />
|
||||
<result property="roleKey" column="role_key" />
|
||||
<result property="roleSort" column="role_sort" />
|
||||
@@ -148,5 +149,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{roleId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectRolesByTenantId" parameterType="String" resultMap="SysRoleResult">
|
||||
<include refid="selectRoleVo"/>
|
||||
where r.tenant_id = #{tenantId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -30,5 +30,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
(#{item.roleId},#{item.menuId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<delete id="deleteRoleMenuForSync" parameterType="Long">
|
||||
delete from sys_role_menu where role_id in
|
||||
<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
|
||||
#{roleId}
|
||||
</foreach>
|
||||
<if test="menuIds != null and menuIds.size() > 0">
|
||||
and menu_id not in
|
||||
<foreach collection="menuIds" item="menuId" open="(" separator="," close=")">
|
||||
#{menuId}
|
||||
</foreach>
|
||||
</if>
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -6,7 +6,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<resultMap type="SysUser" id="SysUserResult">
|
||||
<id property="userId" column="user_id" />
|
||||
<result property="deptId" column="dept_id" />
|
||||
<result property="organiId" column="organi_id" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="deptId" column="dept_id" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="nickName" column="nick_name" />
|
||||
<result property="email" column="email" />
|
||||
@@ -32,6 +34,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<resultMap id="deptResult" type="SysDept">
|
||||
<id property="deptId" column="dept_id" />
|
||||
<result property="parentId" column="parent_id" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="isTenant" column="is_tenant" />
|
||||
<result property="deptName" column="dept_name" />
|
||||
<result property="ancestors" column="ancestors" />
|
||||
<result property="orderNum" column="order_num" />
|
||||
@@ -41,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<resultMap id="RoleResult" type="SysRole">
|
||||
<id property="roleId" column="role_id" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="roleName" column="role_name" />
|
||||
<result property="roleKey" column="role_key" />
|
||||
<result property="roleSort" column="role_sort" />
|
||||
@@ -226,4 +231,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="unableUser" parameterType="SysUser">
|
||||
update sys_user set status = #{statusChar} where user_id in
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="selectUserIdsByTenantId" resultType="Long">
|
||||
select distinct user_id from sys_user
|
||||
where tenant_id = #{tenantId}
|
||||
</select>
|
||||
|
||||
<update id="updateTenantIdOfUsers">
|
||||
<if test="deptIds != null and deptIds.size() > 0">
|
||||
update sys_user set tenant_id = #{tenantId} where dept_id in
|
||||
<foreach collection="deptIds" item="deptId" open="(" close=")" separator=",">
|
||||
#{deptId}
|
||||
</foreach>
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<select id="selectUserByUserNameAndTenantId" resultMap="SysUserResult">
|
||||
<include refid="selectUserVo"/>
|
||||
where u.del_flag = '0' and (u.status is not null or u.status =0) and u.user_name = #{userName} and u.tenant_id = #{tenantId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -7,6 +7,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<resultMap type="SysDept" id="SysDeptResult">
|
||||
<id property="deptId" column="dept_id" />
|
||||
<result property="parentId" column="parent_id" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="isTenant" column="is_tenant" />
|
||||
<result property="ancestors" column="ancestors" />
|
||||
<result property="deptName" column="dept_name" />
|
||||
<result property="orderNum" column="order_num" />
|
||||
@@ -177,4 +179,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
update sys_dept set del_flag = '2' where dept_id = #{deptId}
|
||||
</delete>
|
||||
|
||||
<update id="updateDeptByTenantId">
|
||||
update sys_dept
|
||||
<set>
|
||||
<if test="dept.parentId != null and dept.parentId != 0">parent_id = #{dept.parentId},</if>
|
||||
<if test="dept.deptName != null and dept.deptName != ''">dept_name = #{dept.deptName},</if>
|
||||
<if test="dept.ancestors != null and dept.ancestors != ''">ancestors = #{dept.ancestors},</if>
|
||||
<if test="dept.orderNum != null">order_num = #{dept.orderNum},</if>
|
||||
<if test="dept.leader != null">leader = #{dept.leader},</if>
|
||||
<if test="dept.phone != null">phone = #{dept.phone},</if>
|
||||
<if test="dept.email != null">email = #{dept.email},</if>
|
||||
<if test="dept.status != null and dept.status != ''">status = #{dept.status},</if>
|
||||
<if test="dept.updateBy != null and dept.updateBy != ''">update_by = #{dept.updateBy},</if>
|
||||
<if test="dept.isTenant != null and dept.isTenant != ''">is_tenant = #{dept.isTenant},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where tenant_id = #{tenantId,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
<select id="selectByTenantId" parameterType="String" resultMap="SysDeptResult">
|
||||
<include refid="selectDeptVo"/>
|
||||
where d.del_flag = '0' and d.tenant_id = #{tenantId}
|
||||
</select>
|
||||
|
||||
<select id="selectAllZSByDeptId" parameterType="Long" resultType="long">
|
||||
select dept_id
|
||||
from sys_dept
|
||||
where find_in_set(#{deptId}, ancestors)
|
||||
</select>
|
||||
|
||||
<update id="updateTenantId">
|
||||
<if test="deptIds != null and deptIds.size() > 0">
|
||||
update sys_dept
|
||||
set tenant_id = #{tenantId}
|
||||
where dept_id in
|
||||
<foreach collection="deptIds" item="deptId" index="index"
|
||||
separator="," open="(" close=")">
|
||||
#{deptId}
|
||||
</foreach>
|
||||
</if>
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
10
pom.xml
10
pom.xml
@@ -212,11 +212,19 @@
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.25</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modules>
|
||||
<module>fp-admin</module>
|
||||
<module>fp-framework</module>
|
||||
|
||||
Reference in New Issue
Block a user