1.4 对接SaaS代码实现
根据前边接口SaaS步骤 的分析,需要在商户平台 完成新增员工、新增门店、设置门店管理员等功能。
1.4.1 商户服务新增门店接口
1.4.1.1 接口定义
在商户服务定义新增门店接口
1、接口描述如下:
1)商户注册的同时新增默认门店
2、接口定义如下:
生成StoreDTO类。
在MerchantService接口类中定义如下接口:
/**
\* 商户下新增门店
\* @param storeDTO
*/
StoreDTO createStore(StoreDTO storeDTO) throws BusinessException;
1.4.1.2 接口实现
编写StoreConvert。
package com.huiminpay.merchant.convert;
import com.huiminpay.merchant.api.dto.StoreDTO;
import com.huiminpay.merchant.entity.Store;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface StoreConvert {
StoreConvert INSTANCE = Mappers.getMapper(StoreConvert.class);
StoreDTO entity2dto(Store entity);
Store dto2entity(StoreDTO dto);
List<StoreDTO> listentity2dto(List<Store> staff);
}
在MerchantServiceImpl类中实现createStore方法。
/**
* 商户下 新增门店
* @author glls
* @param storeDTO
* @return com.huiminpay.merchant.api.dto.StoreDTO
* @date 2021/2/27 11:48
*/
@Override
public StoreDTO createStore(StoreDTO storeDTO) throws BusinessException {
Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);
log.info("商户下新增门店"+ JSON.toJSONString(store));
storeMapper.insert(store);
return StoreConvert.INSTANCE.entity2dto(store);
}
1.4.2 商户服务新增员工接口
1.4.2.1 接口定义
在商户服务定义新增员工接口
1、接口描述如下:
1)接收商户填写的员工数据
2)请求商户服务进行新增员工
员工的账号和手机号需要保持唯一性。
3)返回结果
2、接口定义如下:
生成StaffDTO类。 员工信息类
在MerchantService接口类中定义如下接口:
/**
* 商户新增员工
* @param staffDTO
*/
StaffDTO createStaff(StaffDTO staffDTO) throws BusinessException;
1.4.2.2 接口实现
编写StaffConvert。
package com.huiminpay.merchant.convert;
import com.huiminpay.merchant.api.dto.StaffDTO;
import com.huiminpay.merchant.entity.Staff;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface StaffConvert {
StaffConvert INSTANCE = Mappers.getMapper(StaffConvert.class);
StaffDTO entity2dto(Staff entity);
Staff dto2entity(StaffDTO dto);
List<StaffDTO> listentity2dto(List<Staff> staff);
}
在MerchantServiceImpl类中定义createStaff方法:
@Autowired
private StaffMapper staffMapper;
/**
* 商户下 新增员工
* @param staffDTO
*/
@Override
public StaffDTO createStaff(StaffDTO staffDTO) throws BusinessException {
//1.校验手机号格式及是否存在
String mobile = staffDTO.getMobile();
if(StringUtils.isBlank(mobile)){
throw new BusinessException(CommonErrorCode.E_100112);
}
//根据商户id和手机号校验唯一性
if(isExistStaffByMobile(mobile, staffDTO.getMerchantId())){
throw new BusinessException(CommonErrorCode.E_100113);
}
//2.校验用户名是否为空
String username = staffDTO.getUsername();
if(StringUtils.isBlank(username)){
throw new BusinessException(CommonErrorCode.E_100110);
}
//根据商户id和账号校验唯一性
if(isExistStaffByUserName(username, staffDTO.getMerchantId())){
throw new BusinessException(CommonErrorCode.E_100114);
}
Staff entity = StaffConvert.INSTANCE.dto2entity(staffDTO);
log.info("商户下新增员工");
staffMapper.insert(entity);
return StaffConvert.INSTANCE.entity2dto(entity);
}
/**
* 根据手机号判断员工是否已在指定商户存在
* @param mobile 手机号
* @return
*/
private boolean isExistStaffByMobile(String mobile, Long merchantId) {
LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<Staff>();
lambdaQueryWrapper.eq(Staff::getMobile, mobile).eq(Staff::getMerchantId, merchantId);
int i = staffMapper.selectCount(lambdaQueryWrapper);
return i > 0;
}
/**
* 根据账号判断员工是否已在指定商户存在
* @param userName
* @param merchantId
* @return
*/
private boolean isExistStaffByUserName(String userName, Long merchantId) {
LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<Staff>();
lambdaQueryWrapper.eq(Staff::getUsername, userName).eq(Staff::getMerchantId,merchantId);
int i = staffMapper.selectCount(lambdaQueryWrapper);
return i > 0;
}
1.4.3 商户服务门店设置管理员接口
1.4.3.1 接口定义
1、接口描述如下:绑定门店和员工对应关系
2、接口定义如下:
在MerchantService接口类中定义如下接口:
/**
* 为门店设置管理员
* @param storeId
* @param staffId
* @throws BusinessException
*/
void bindStaffToStore(Long storeId, Long staffId) throws BusinessException;
1.4.3.2 接口实现
在MerchantServiceImpl实现bindStaffToStore。
/**
* 给门店设置管理员
* @author glls
* @param storeId 门店id
* @param staffId 员工id
* @return void
* @date 2021/2/27 13:00
*/
@Override
public void bindStaffToStore(Long storeId, Long staffId) throws BusinessException {
StoreStaff storeStaff = new StoreStaff();
storeStaff.setStoreId(storeId);
storeStaff.setStaffId(staffId);
storeStaffMapper.insert(storeStaff);
}
1.4.4 商户服务商户注册接口修改
1.4.4.1 接口说明
SaaS系统的用户服务提供注册租户的接口,如下 :
/**
* 创建租户
* 新增租户、新增租户管理员,同时初始化套餐
* 1.若管理员用户名已存在(目前不会出现,用户名内部随机生成)
* 2.手机号已存在,禁止创建
* @param createTenantRequest 创建租户请求信息
* @return
*/
TenantDTO createTenantAndAccount(CreateTenantRequestDTO createTenantRequest);
接口参数:
1、手机号
2、账号
3、密码
4、租户类型:huimin-merchant 5、默认套餐:huimin-merchant
6、租户名称,同账号名
1.4.4.2 接口实现
1、添加SaaS的用户服务API依赖:打开huiminpay-merchant-service工程的pom.xml
<dependency>
<groupId>com.huiminpay</groupId>
<artifactId>huiminpay-user-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2、MerchantServiceImpl,完善createMerchant()方法:
/**
* 注册商户服务接口,接收账号、密码、手机号,为了可扩展性使用merchantDto接收数据
*
* 调用SaaS接口: 新增租户 用户 绑定租户和用户的关系 初始化权限
* @param merchantDTO 商户注册信息
* @return 注册成功的商户信息
*/
@Override
@Transactional
public MerchantDTO createMerchant(MerchantDTO merchantDTO) throws BusinessException {
// 1.校验
if (merchantDTO == null) {
throw new BusinessException(CommonErrorCode.E_100108);
}
//手机号非空校验
if (StringUtils.isBlank(merchantDTO.getMobile())) {
throw new BusinessException(CommonErrorCode.E_100112);
}
//校验手机号的合法性
if (!PhoneUtil.isMatches(merchantDTO.getMobile())) {
throw new BusinessException(CommonErrorCode.E_100109);
}
//联系人非空校验
if (StringUtils.isBlank(merchantDTO.getUsername())) {
throw new BusinessException(CommonErrorCode.E_100110);
}
//密码非空校验
if (StringUtils.isBlank(merchantDTO.getPassword())) {
throw new BusinessException(CommonErrorCode.E_100111);
}
//校验商户手机号的唯一性,根据商户的手机号查询商户表,如果存在记录则说明已有相同的手机号重复
LambdaQueryWrapper<Merchant> lambdaQryWrapper = new LambdaQueryWrapper<Merchant>()
.eq(Merchant::getMobile,merchantDTO.getMobile());
Integer count = merchantMapper.selectCount(lambdaQryWrapper);
if(count>0){
throw new BusinessException(CommonErrorCode.E_100113);
}
//2.调用SaaS接口 添加 租户并绑定和门店 员工 商户之间的关系
/**
1、手机号
2、账号
3、密码
4、租户类型:huimin-merchant
5、默认套餐:huimin-merchant
6、租户名称,同账号名
*/
CreateTenantRequestDTO createTenantRequestDTO = new CreateTenantRequestDTO();
createTenantRequestDTO.setMobile(merchantDTO.getMobile());
//租户的账号信息
createTenantRequestDTO.setUsername(merchantDTO.getUsername());
createTenantRequestDTO.setPassword(merchantDTO.getPassword());
//表示该租户类型是商户
createTenantRequestDTO.setTenantTypeCode("huimin-merchant");//租户类型
//设置租户套餐为初始化套餐餐 //套餐,根据套餐进行分配权限
createTenantRequestDTO.setBundleCode("huimin-merchant");
//租户名称,和账号名一样
createTenantRequestDTO.setName(merchantDTO.getUsername());
//如果租户在SaaS已经存在,SaaS直接 返回此租户的信息,否则进行添加
TenantDTO tenantAndAccount = tenantService.createTenantAndAccount(createTenantRequestDTO);
//获取租户的id
if(tenantAndAccount == null || tenantAndAccount.getId() == null){
throw new BusinessException(CommonErrorCode.E_200012);
}
//租户的id
Long tenantId = tenantAndAccount.getId();
//租户id在商户表唯一 租户 和 商户 是 一一对应的, 商户就是在 saas 中的租户
//根据租户id从商户表查询,如果存在记录则不允许添加商户
Integer count1 = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>().eq(Merchant::getTenantId, tenantId));
if(count1>0){
throw new BusinessException(CommonErrorCode.E_200017);
}
// 3. 设置 租户 和 商户 绑定关系
//将dto转成entity
Merchant entity = MerchantConvert.INSTANCE.dto2entity(merchantDTO);
//设置所对应的租户的Id
entity.setTenantId(tenantId); // 设置 商户 所属的租户id 注意 商户和租户是一一对应的
//设置审核状态0‐未申请,1‐已申请待审核,2‐审核通过,3‐审核拒绝
entity.setAuditStatus("0");
//保存商户信息
merchantMapper.insert(entity);
//4.新增门店 创建根门店
StoreDTO storeDTO = new StoreDTO();
storeDTO.setStoreName("根门店");
storeDTO.setMerchantId(entity.getId());//商户id 也是 租户id
StoreDTO store = createStore(storeDTO);
//5.新增员工
StaffDTO staffDTO = new StaffDTO();
staffDTO.setMobile(merchantDTO.getMobile());//手机号
staffDTO.setUsername(merchantDTO.getUsername());//账号
// 给员工设置所属门店 此处为根门店
staffDTO.setStoreId(store.getId());//员所属门店id
staffDTO.setMerchantId(entity.getId());//商户id
StaffDTO staff = createStaff(staffDTO);
//6.为门店设置管理员
bindStaffToStore(store.getId(), staff.getId());
//将entity转成 dto
MerchantDTO merchantDTONew = MerchantConvert.INSTANCE.entity2dto(entity);
return merchantDTONew;
}
1.4.4.2 测试
使用Postman进行商户注册,请求:http://localhost:57010/merchant/merchants/register
注册成功后观察huiminpay_user数据库下的account、tenant、tenant_account表是否有新注册的账号、租户信息。