Oam接入企业微信;调整品牌管理;添加初始化角色;调整商城分账

This commit is contained in:
DB 2023-11-22 16:02:37 +08:00
parent 2f4f481a24
commit c34719a476
30 changed files with 371 additions and 67 deletions

View File

@ -16,6 +16,10 @@ public enum InitRoleEnum {
* MALL超级管理员角色
*/
SUPER_MALL_ROLE("2", "SuperMallAdmin", "SuperMallAdmin", -1, UserType.MALL_USER),
/**
* 企微注册初始化角色
*/
WX_CP_INIT_ROLE("3", "企微注册通用角色", "RegisterRole", 0, UserType.OAM_USER),
;
/**

View File

@ -43,6 +43,11 @@ public class SysUser extends BaseEntity implements Serializable {
*/
private String password;
/**
* rsa加密后的密码
*/
private String rsaPassword;
/**
* 昵称
*/

View File

@ -49,9 +49,10 @@ public class LoginFailureHandler implements AuthenticationFailureHandler {
if(e instanceof CpopAuthenticationException) {
loginUser.setUserType((UserType) ((CpopAuthenticationException) e).getParams());
errorMessage = e.getMessage();
result = R.ok(errorMessage);
}else {
result = R.fail(errorMessage);
}
//TODO暂时先这么处理
result = R.ok(errorMessage);
if (loginUser.getUserType() == UserType.OAM_USER || loginUser.getUserType() == UserType.MINI_USER) {
//添加登录失败日志
coreService.insertOperationLog(Constants.FAIL, OperationLogEnum.SYSTEM_LOGIN, loginUser, errorMessage);

View File

@ -122,6 +122,16 @@ public interface CoreService {
*/
LoginUser loadUserByUsername(String userName, UserType userType);
/**
* @descriptions 根据手机号与用户类型获取用户信息
* @author DB
* @date 2023/10/19 9:57
* @param phoneNumber 手机号
* @param userType 用户类型
* @return 登陆用户
*/
LoginUser loadUserByPhone(String phoneNumber, UserType userType);
/**
* @descriptions 根据手机号与用户类型获取用户信息
* @author DB

View File

@ -220,6 +220,21 @@ public class CoreServiceImpl implements CoreService {
return userType.getStrategy().getLoginUserInfo(sysUser, null);
}
/**
* @descriptions 可能存在用户手机号登陆的情况
* @author DB
* @date 2023/11/21 10:05
* @param phoneNumber 手机号
* @param userType 用户类型
* @return: com.cpop.core.base.entity.LoginUser
*/
@Override
public LoginUser loadUserByPhone(String phoneNumber, UserType userType) {
//统一获取系统用户信息
SysUser sysUser = this.getSysUserByPhone(phoneNumber, userType);
return userType.getStrategy().getLoginUserInfo(sysUser, null);
}
/**
* @descriptions 根据手机号与用户类型获取用户信息
* @author DB

View File

@ -6,7 +6,6 @@ import com.cpop.core.base.entity.loginInfo.MiniUserLoginInfo;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.CpopAuthenticationException;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysUser;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.DbChain;
@ -98,9 +97,6 @@ public class MiniLoginStrategy implements LoginStrategy {
if (brand == null) {
throw new CpopAuthenticationException("用户登陆失败,果酱品牌暂未录入系统");
}
if (!brand.getBoolean("isOpenMall")){
throw new CpopAuthenticationException("用户登陆失败,当前品牌暂未开通分账");
}
//构建用户信息
Row row = DbChain.table("cp_mini_user")
.select("cmu.id","cmu.open_id","cmu.app_id","cmu.user_id","cmu.brand_id","cmu.nick_name","cmu.avatar","cmu.source_type")

View File

@ -195,6 +195,9 @@
<if test="password != null and password != ''">
password,
</if>
<if test="rsaPassword != null and rsaPassword != ''">
rsa_password,
</if>
<if test="nickName != null and nickName != ''">
nick_name,
</if>
@ -241,6 +244,9 @@
<if test="password != null and password != ''">
#{password},
</if>
<if test="rsaPassword != null and rsaPassword != ''">
#{rsaPassword},
</if>
<if test="nickName != null and nickName != ''">
#{nickName},
</if>

View File

@ -12,6 +12,7 @@ import com.cpop.system.business.service.BrandService;
import com.cpop.system.business.service.ProfitSharingService;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingFinishRequest;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingQueryRequest;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingQueryResult;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingReceiverRequest;
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingResult;
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingReturnRequest;
@ -57,13 +58,13 @@ public class CpopWxPayTests {
WxPayRefundV3Request.Amount amount = new WxPayRefundV3Request.Amount();
//退款金额(单位分)
//int refund = order.getTotalAmount().scaleByPowerOfTen(2).intValue();
int refund = 100;
int refund = 500;
amount.setRefund(refund)
.setTotal(refund)
.setCurrency("CNY");
request.setSubMchid(wxPayService.getConfig().getSubMchId())
.setTransactionId("4200002044202311178101861880")
.setOutTradeNo("83081335475826688")
.setTransactionId("4200002010202311202693854147")
.setOutTradeNo("84052505520087040")
//.setTransactionId(order.getOutOrderNo())
//.setOutTradeNo(order.getId())
.setNotifyUrl(wxPayProperties.getNotifyRefund())
@ -133,6 +134,21 @@ public class CpopWxPayTests {
System.out.println(wxPayOrderQueryResult);
}
/**
* @descriptions 查询分账结果
* @author DB
* @date 2023/11/20 12:35
* @return: void
*/
@Test
public void getSharingInfo() throws WxPayException {
ProfitSharingQueryRequest profitSharingQueryRequest = new ProfitSharingQueryRequest();
profitSharingQueryRequest.setOutOrderNo("84064193241784320").setTransactionId("4200002009202311209353972307");
profitSharingQueryRequest.setSubMchId("1659765332");
ProfitSharingQueryResult result = wxPayService.getProfitSharingService().profitSharingQuery(profitSharingQueryRequest);
System.out.println(result.getResultCode());
}
/**
* @descriptions 查询分账结果
* @author DB
@ -141,7 +157,7 @@ public class CpopWxPayTests {
*/
@Test
public void getRefundResult() throws WxPayException {
ProfitSharingResult profitSharingResult = wxPayService.getProfitSharingV3Service().getProfitSharingResult("83081464408731648", "4200002044202311178101861880", "1659765332");
ProfitSharingResult profitSharingResult = wxPayService.getProfitSharingV3Service().getProfitSharingResult("84052505520087040", "4200002010202311202693854147", "1659765332");
System.out.println(profitSharingResult);
}
@ -152,8 +168,8 @@ public class CpopWxPayTests {
@Test
public void profitSharingFinish() throws WxPayException {
ProfitSharingFinishRequest profitSharingFinishRequest = new ProfitSharingFinishRequest();
profitSharingFinishRequest.setTransactionId("4200002044202311178101861880");
profitSharingFinishRequest.setOutOrderNo("83081335475826688");
profitSharingFinishRequest.setTransactionId("4200002010202311202693854147");
profitSharingFinishRequest.setOutOrderNo("84052505520087040");
profitSharingFinishRequest.setDescription("结束分账");
profitSharingFinishRequest.setSubMchId("1659765332");
wxPayService.getProfitSharingService().profitSharingFinish(profitSharingFinishRequest);

View File

@ -6,6 +6,7 @@ import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.common.utils.ip.IpUtils;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.enums.OrderSource;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysUser;
@ -303,9 +304,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
//查询是否是服务商系品牌
String brandId = loginUserInfo.getString("brandId");
Brand brand = SpringUtils.getBean(BrandService.class).getById(brandId);
//需要分账
if (order.getTotalAmount().scaleByPowerOfTen(2).intValue() >= 100) {
if (order.getTotalAmount().scaleByPowerOfTen(2).intValue() >= Math.ceil(1 / OrderSource.MALL.getRate())) {
//需要分账
orderRequest.setProfitSharing("Y");
}
@ -529,10 +529,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
.where(ORDER_DETAIL.ORDER_ID.eq(orderId)).list();
//订单数量集合
Map<String, Integer> orderNumMap = orderDetails.stream().collect(Collectors.toMap(OrderDetail::getProductRecordId, OrderDetail::getNumber));
//查询订单信息
Order order = this.getById(orderId);
//需要分账(金额大于1元才分账)
if (notifyResult.getTotalFee() >= 100) {
//需要分账
if (notifyResult.getTotalFee() >= Math.ceil(1 / OrderSource.MALL.getRate())) {
wxPayAsyncTask.asyncWxPayProfitSharing(orderId, notifyResult, wxPayService);
}
//异步更新

View File

@ -9,6 +9,7 @@ import com.cpop.core.base.exception.UtilException;
import com.cpop.core.utils.SpringUtils;
import com.cpop.mall.framework.config.wxPay.WxPayProperties;
import com.cpop.system.business.entity.ProfitSharing;
import com.cpop.system.business.service.BrandService;
import com.cpop.system.business.service.ProfitSharingService;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingReceiverRequest;
@ -27,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.cpop.system.business.entity.table.BrandTableDef.BRAND;
import static com.cpop.system.business.entity.table.ProfitSharingTableDef.PROFIT_SHARING;
/**
@ -84,18 +86,6 @@ public class WxPayAsyncTask {
mapReceiver.put("account", wxPayProperties.getSharingAccount());
mapReceiver.put("amount", ceil.longValue());
mapReceiver.put("description","分账到服务商");
//TODO:V3版本目前发送失败
/*
ProfitSharingReceiverRequest profitSharingReceiver = new ProfitSharingReceiverRequest();
profitSharingReceiver.setReceiver();
ProfitSharingReceiver profitSharingReceiver = new ProfitSharingReceiver();
profitSharingReceiver.setType("MERCHANT_ID");
profitSharingReceiver.setAccount(wxPayProperties.getSharingAccount());
profitSharingReceiver.setRelationType("SERVICE_PROVIDER");
profitSharingReceiver.setAmount(ceil.longValue());
profitSharingReceiver.setName("果酱盒子");
profitSharingReceiver.setDescription("分账到服务商");
*/
List<Map<String, Object>> receivers = new ArrayList<>();
receivers.add(mapReceiver);
//分账请求参数
@ -131,6 +121,8 @@ public class WxPayAsyncTask {
}
} catch (WxPayException e) {
if (flag > 5) {
//关闭商城支付
SpringUtils.getBean(BrandService.class).updateChain().set(BRAND.IS_OPEN_SHARING, false).where(BRAND.WX_MCH_ID.eq(wxPayService.getConfig().getSubMchId())).update();
throw new ServiceException(e.getMessage());
} else {
//重复调用

View File

@ -2,6 +2,7 @@ package com.cpop.mall.framework.handler;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.system.business.entity.Brand;
@ -37,6 +38,10 @@ public class WxPayHandler {
}
String brandId = loginUserInfo.getString("brandId");
Brand brand = SpringUtils.getBean(BrandService.class).getById(brandId);
//检查是否开启分账
if (!brand.getIsOpenSharing()) {
throw new ServiceException("当前商户暂未开启分账,请联系相关客服");
}
WxPayConfig payConfig = wxPayService.getConfig();
//子商户信息
payConfig.setSubMchId(StringUtils.trimToNull(brand.getWxMchId()));

View File

@ -4,7 +4,7 @@ cpop:
profile: E:/Cpop/uploadPath
jwt:
#白名单
whiteList: /login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources
whiteList: /login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxCp/*,/wxCp/portal/*/registerCode
gateway:
rsa-keypair:
# 公钥文件
@ -54,7 +54,7 @@ mybatis-flex:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
datasource:
mall:
oam:
url: jdbc:mysql://sh-cynosdbmysql-grp-fggo83js.sql.tencentcdb.com:20965/cpop_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: Customer0401
@ -84,7 +84,7 @@ knife4j:
api-rule-resources:
- com.cpop.oam
#微信支付
#微信
wx:
pay:
# p12证书的位置可以指定绝对路径也可以指定类路径以classpath:开头)

View File

@ -4,7 +4,7 @@ cpop:
profile: /root/cpop-union/cpop-oam/upload
jwt:
#白名单
whiteList: /login,/getCaptcha,/profile/**,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*
whiteList: /login,/getCaptcha,/profile/**,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*,/wxCp/*,/wxCp/portal/*/registerCode
#拦截
gateway:
rsa-keypair:

View File

@ -4,7 +4,7 @@ cpop:
profile: /root/cpop-union/cpop-mall/upload
jwt:
#白名单
whiteList: /login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*
whiteList: /login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*,/wxCp/portal/*/registerCode,/wxCp/*
#拦截
gateway:
rsa-keypair:

View File

@ -131,7 +131,10 @@ wx:
#企业微信
cp:
corpId: ww9b83a363662f219f
qConnectUrl: https://oam.jamboxsys.com/Cpop-Oam/wxCp/portal/1000024/authCode
#o2认证注册到oam中的地址
oAuth2registerUrl: https://oam.jamboxsys.com/wxCpRegister/
#登陆跳转地址
oAuth2LoginUri: https://oam.jamboxsys.com/wxCpLogin/
appConfigs:
#通讯录
- agentId: 1000000

View File

@ -51,7 +51,7 @@ public class StaffBo implements Serializable {
private String userId;
/**
* 员工类型
* 员工类型(0:技术人员;1:售后人员;2:管理人员)
*/
@NotNull(message = "员工类型不能为空")
@ApiModelProperty(value = "员工类型(0:技术人员;1:售后人员;2:管理人员)",required = true)
@ -118,4 +118,10 @@ public class StaffBo implements Serializable {
@ApiModelProperty(value = "角色id",required = true)
private String roleId;
/**
* 企业微信用户id
*/
@ApiModelProperty(value = "企业微信用户id",required = true)
private String wxCpUserId;
}

View File

@ -2,14 +2,19 @@ package com.cpop.oam.business.controller.backstage;
import com.cpop.core.base.R;
import com.cpop.oam.business.service.OamWxCpService;
import com.cpop.oam.business.vo.WxCpLoginVo;
import com.cpop.oam.framework.config.wxCp.WxCpConfiguration;
import com.cpop.system.business.vo.LoginUserInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.cp.api.WxCpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @author DB
@ -25,6 +30,36 @@ public class WxCpController {
@Autowired
private OamWxCpService oamWxCpService;
@Value("${wx.cp.oAuth2registerUrl}")
private String oAuth2registerUrl;
/**
* @author LOST.yuan
* @Description 根据code换取用户信息
* @date 14:52 2022/9/7
* @return {@link R<LoginUserInfoVo>}
**/
@GetMapping("/getOauth2Url")
@ApiOperation("获取oauth2认证链接")
public R<String> getOauth2Url() {
WxCpService cpService = WxCpConfiguration.getCpService(1000024);
String authUrl = cpService.getOauth2Service().buildAuthorizationUrl(oAuth2registerUrl, null, "snsapi_privateinfo");
return R.ok(authUrl);
}
/**
* @author LOST.yuan
* @Description 根据code换取用户信息
* @date 14:52 2022/9/7
* @return {@link R<LoginUserInfoVo>}
**/
@GetMapping("/loginUserInfoByCode")
@ApiOperation("根据code换取用户信息")
public R<WxCpLoginVo> loginUserInfoByCode(HttpServletRequest httpServletRequest, @RequestParam("code") String code) {
WxCpLoginVo loginVo = oamWxCpService.loginUserInfoByCode(httpServletRequest, code);
return R.ok(loginVo);
}
/**
* @return R<Void>
* @Description: 同步企业微信部门

View File

@ -51,9 +51,9 @@ public class WxPayController {
* @return: com.cpop.core.base.R<java.lang.Void>
*/
@PreAuthorize("@aps.hasPermission('brandStore:brand:update')")
@ApiOperation("开通品牌商城")
@PutMapping("/changeBrandMall")
public R<Void> changeWechatSharing(@RequestBody @Validated ChangeWechatSharingBo bo) {
@ApiOperation("开通微信分账")
@PutMapping("/changeBrandSharing")
public R<Void> changeBrandSharing(@RequestBody @Validated ChangeWechatSharingBo bo) {
//获取品牌下属商户
Brand brand = brandService.getById(bo.getBrandId());
if (StringUtils.isBlank(brand.getWxMchId())) {
@ -66,12 +66,11 @@ public class WxPayController {
//添加分账接收方
ProfitSharingReceiverRequest profitSharingReceiver = new ProfitSharingReceiverRequest();
//开启
if (bo.getIsOpenMall()) {
if (bo.getIsOpenSharing()) {
mapReceiver.put("relation_type", "SERVICE_PROVIDER");
mapReceiver.put("name", wxPayConfiguration.getProperties().getSharingAccountName());
profitSharingReceiver.setReceiver(JSONObject.toJSONString(mapReceiver));
WxPayConfig config = wxPayService.getConfig();
config.setSubMchId(brand.getWxMchId());
try {
wxPayService.getProfitSharingService().addReceiver(profitSharingReceiver);
@ -89,7 +88,7 @@ public class WxPayController {
throw new ServiceException(e.getMessage());
}
}
brandService.updateChain().set(BRAND.IS_OPEN_MALL, bo.getIsOpenMall()).where(BRAND.ID.eq(bo.getBrandId())).update();
brandService.updateChain().set(BRAND.IS_OPEN_SHARING, bo.getIsOpenSharing()).where(BRAND.ID.eq(bo.getBrandId())).update();
return R.ok();
}
}

View File

@ -4,6 +4,7 @@ import com.cpop.common.utils.JsonUtils;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.SpringUtils;
import com.cpop.oam.business.service.OamWxCpService;
import com.cpop.oam.framework.config.wxCp.WxCpConfiguration;
import com.cpop.oam.framework.constant.WxCpConstant;
import io.swagger.annotations.Api;
@ -14,6 +15,7 @@ import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
@ -28,6 +30,9 @@ public class WxCpPortalController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private OamWxCpService oamWxCpService;
@GetMapping(produces = "text/plain;charset=utf-8")
public String authGet(@PathVariable Integer agentId,
@RequestParam(name = "msg_signature", required = false) String signature,
@ -80,4 +85,20 @@ public class WxCpPortalController {
return null;
}
/**
* @descriptions 企微的o2认证可查询用户敏感信息
* @author DB
* @date 2023/11/17 14:42
* @param agentId 企业微信服务应用id
* @param code 授权码
* @param state 信息 注册
* @return: java.lang.String
*/
@GetMapping(produces = "text/plain;charset=utf-8", value = "/registerCode")
public void registerCode(@PathVariable Integer agentId,
@RequestParam("code") String code,
@RequestParam("state") String state) {
oamWxCpService.registerCode(agentId, code);
}
}

View File

@ -1,5 +1,9 @@
package com.cpop.oam.business.service;
import com.cpop.oam.business.vo.WxCpLoginVo;
import javax.servlet.http.HttpServletRequest;
/**
* Oam暴露的企业微信接口
* @author DB
@ -21,4 +25,23 @@ public interface OamWxCpService {
* @return: void
*/
void syncWxCpStaff();
/**
* @descriptions 根据code换取用户信息
* @author DB
* @date 2023/11/20 18:19
* @param code code
* @return: void
*/
WxCpLoginVo loginUserInfoByCode(HttpServletRequest httpServletRequest, String code);
/**
* @descriptions 企微的o2认证可查询用户敏感信息
* @author DB
* @date 2023/11/21 15:31
* @param agentId 应用id
* @param code 授权码
* @return: void
*/
void registerCode(Integer agentId, String code);
}

View File

@ -1,5 +1,6 @@
package com.cpop.oam.business.service;
import com.cpop.core.base.table.SysUser;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.cpop.oam.business.bo.ModifyUserPasswordBo;
@ -40,7 +41,7 @@ public interface StaffService extends IService<Staff> {
* @date 2023/09/08 14:12
* @param bo 请求参数
*/
void insertStaff(StaffBo bo);
SysUser insertStaff(StaffBo bo);
/**
* @descriptions 修改员工

View File

@ -1,12 +1,14 @@
package com.cpop.oam.business.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.enums.InitRoleEnum;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysUser;
import com.cpop.core.mapper.CoreMapper;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.*;
import com.cpop.core.utils.uuid.IdUtils;
import com.cpop.oam.business.bo.StaffBo;
import com.cpop.oam.business.entity.Dept;
import com.cpop.oam.business.entity.Staff;
import com.cpop.oam.business.entity.StaffMidDept;
@ -14,25 +16,37 @@ import com.cpop.oam.business.service.DeptService;
import com.cpop.oam.business.service.OamWxCpService;
import com.cpop.oam.business.service.StaffMidDeptService;
import com.cpop.oam.business.service.StaffService;
import com.cpop.oam.business.vo.WxCpLoginVo;
import com.cpop.oam.framework.config.wxCp.WxCpConfiguration;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpOAuth2Service;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.WxCpUserDetail;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
import static com.cpop.core.base.table.table.SysUserTableDef.SYS_USER;
import static com.cpop.oam.business.entity.table.DeptTableDef.DEPT;
import static com.cpop.oam.business.entity.table.StaffTableDef.STAFF;
/**
* @author DB
* @createTime 2023/11/17 9:42
* @description Oam暴露的企业微信接口
*/
@Slf4j
@Service("oamWxCpService")
public class OamWxCpServiceImpl implements OamWxCpService {
@ -149,4 +163,97 @@ public class OamWxCpServiceImpl implements OamWxCpService {
throw new ServiceException(e.getMessage());
}
}
/**
* @descriptions 根据code换取用户信息
* @author DB
* @date 2023/11/20 18:19
* @param code code
* @return: void
*/
@Override
public WxCpLoginVo loginUserInfoByCode(HttpServletRequest httpServletRequest, String code) {
WxCpService cpService = WxCpConfiguration.getCpService(1000024);
try {
//获取用户信息
WxCpOAuth2Service oauth2Service = cpService.getOauth2Service();
//此处只能获取企业微信的userId
WxCpOauth2UserInfo userInfo = oauth2Service.getUserInfo(1000024, code);
String wxCpUserId = userInfo.getUserId();
//查询用户信息
Row row = Db.selectOneByQuery("cp_sys_user",
QueryWrapper.create().select(SYS_USER.ALL_COLUMNS)
.leftJoin(STAFF).on(STAFF.USER_ID.eq(SYS_USER.ID))
.where(STAFF.WX_CP_USER_ID.eq(wxCpUserId)));
if (null == row){
throw new ServiceException("请先在企微上的Oam应用中进行注册");
}
SysUser sysUser = RowUtil.toEntity(row, SysUser.class);
return new WxCpLoginVo(sysUser.getUserName(),sysUser.getRsaPassword());
} catch (WxErrorException e) {
throw new ServiceException(e.getMessage());
}
}
/**
* @descriptions 企微的o2认证可查询用户敏感信息
* @author DB
* @date 2023/11/21 15:31
* @param agentId 应用id
* @param code 授权码
* @return: void
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void registerCode(Integer agentId, String code) {
WxCpService cpService = WxCpConfiguration.getCpService(agentId);
//获取用户信息
WxCpOAuth2Service oauth2Service = cpService.getOauth2Service();
try {
WxCpOauth2UserInfo userInfo = oauth2Service.getUserInfo(agentId, code);
//获取用户敏感信息
WxCpUserDetail userDetail = oauth2Service.getUserDetail(userInfo.getUserTicket());
//此时可以获取敏感信息
if (StringUtils.isBlank(userDetail.getMobile())){
throw new ServiceException("请重新扫码并授权敏感信息!");
}
//读取员工信息
StaffService staffService = SpringUtils.getBean(StaffService.class);
long count = staffService.queryChain().where(STAFF.WX_CP_USER_ID.eq(userDetail.getUserId())).count();
if (count > 0) {
throw new ServiceException("您已通过注册,请扫码或直接通过用户名密码登陆!");
}
//获取部门信息
WxCpUser wxCpUser = cpService.getUserService().getById(userInfo.getUserId());
List<Dept> deptList = SpringUtils.getBean(DeptService.class).list();
Map<Long, Dept> wxCpDeptMap = deptList.stream().collect(Collectors.toMap(Dept::getWxCpId, item -> item));
//创建员工
StaffBo staffBo = new StaffBo();
String deptIds = "";
//调整部门数据
for (Long departId : wxCpUser.getDepartIds()) {
Dept dept = wxCpDeptMap.get(departId);
if (dept != null) {
if (StringUtils.isBlank(deptIds)) {
deptIds = deptIds + dept.getId();
} else {
deptIds = deptIds + "," + dept.getId();
}
}
}
String encrypt = SpringUtils.getBean(RsaUtils.class).encrypt(userDetail.getMobile());
//读取用户通用信息
staffBo.setUserName(userDetail.getMobile()).setName(wxCpUser.getName()).setNickName(wxCpUser.getAlias()).setAvatar(userDetail.getAvatar()).setEmail(userDetail.getBizMail()).setPhoneNumber(userDetail.getMobile())
.setSex(!StringUtils.equals(userDetail.getGender(), "1")).setStatus(true).setStaffType(2).setWxCpUserId(wxCpUser.getUserId())
//密码默认为手机号
.setPassword(encrypt)
//设置部门
.setDeptId(deptIds)
.setRoleId(InitRoleEnum.WX_CP_INIT_ROLE.getId());
//保存员工
staffService.insertStaff(staffBo);
} catch (WxErrorException e) {
throw new ServiceException(e.getMessage());
}
}
}

View File

@ -51,10 +51,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static com.cpop.core.base.table.table.SysOperationLogTableDef.SYS_OPERATION_LOG;
@ -118,7 +115,7 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void insertStaff(StaffBo bo) {
public SysUser insertStaff(StaffBo bo) {
//先添加用户信息
SysUser sysUser;
if (validatedUserInfo(bo)) {
@ -127,12 +124,18 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
//用户名-手机-邮箱都需要做唯一校验
sysUser = BeanUtils.mapToClass(bo, SysUser.class);
//解密与重设密码
sysUser.setRsaPassword(bo.getPassword());
decryptAndResetPasswords(sysUser);
sysUser.setId(IdUtils.fastSimpleUUID());
//获取当前创建人员信息
LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
sysUser.setCreateUserId(loginUser.getUserId());
sysUser.setUpdateUserId(loginUser.getUserId());
if (loginUser == null){
sysUser.setCreateUserId("1");
sysUser.setUpdateUserId("1");
} else {
sysUser.setCreateUserId(loginUser.getUserId());
sysUser.setUpdateUserId(loginUser.getUserId());
}
sysUser.setUserType(UserType.OAM_USER.toString());
SpringUtils.getBean(CoreService.class).insertSysUser(sysUser);
}
@ -140,6 +143,16 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
Staff sysStaff = BeanUtils.mapToClass(bo, Staff.class);
sysStaff.setUserId(sysUser.getId());
this.save(sysStaff);
//批量导入部门信息
List<String> deptList = Arrays.asList(bo.getDeptId().split(","));
List<StaffMidDept> staffMidDeptList = new ArrayList<>();
deptList.forEach(item -> {
StaffMidDept staffMidDept = new StaffMidDept();
staffMidDept.setDeptId(item).setStaffId(sysStaff.getId());
staffMidDeptList.add(staffMidDept);
});
SpringUtils.getBean(StaffMidDeptService.class).saveBatch(staffMidDeptList);
return sysUser;
}
/**
@ -152,9 +165,9 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
private Boolean validatedUserInfo(StaffBo bo) {
long count = this.count(QueryWrapper.create()
//用户名
.where(SYS_USER.USER_NAME.eq(bo.getUserName()))
.where(SYS_USER.USER_NAME.eq(bo.getUserName()).or(SYS_USER.PHONE_NUMBER.eq(bo.getPhoneNumber())))
//手机号
.or(SYS_USER.PHONE_NUMBER.eq(bo.getPhoneNumber()))
.and(SYS_USER.USER_TYPE.eq(UserType.OAM_USER.toString()))
.from(SYS_USER));
if (StringUtils.isNotBlank(bo.getUserId())) {
return count > 1;
@ -200,6 +213,18 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
//再修改员工信息
Staff sysStaff = BeanUtils.mapToClass(bo, Staff.class);
this.updateById(sysStaff);
//批量删除
StaffMidDeptService staffMidDeptService = SpringUtils.getBean(StaffMidDeptService.class);
staffMidDeptService.remove(QueryWrapper.create().where(STAFF_MID_DEPT.STAFF_ID.eq(sysStaff.getId())));
//批量导入部门信息
List<String> deptList = Arrays.asList(bo.getDeptId().split(","));
List<StaffMidDept> staffMidDeptList = new ArrayList<>();
deptList.forEach(item -> {
StaffMidDept staffMidDept = new StaffMidDept();
staffMidDept.setDeptId(item).setStaffId(sysStaff.getId());
staffMidDeptList.add(staffMidDept);
});
staffMidDeptService.saveBatch(staffMidDeptList);
//获取缓存信息
RedisService redisService = SpringUtils.getBean(RedisService.class);
JSONObject jsonObject = redisService.getCacheObject(UserType.OAM_USER.getKey() + bo.getUserName());

View File

@ -0,0 +1,29 @@
package com.cpop.oam.business.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
/**
* @author DB
* @createTime 2023/11/21 14:38
* @description 企业微信登陆或注册
*/
@Data
@AllArgsConstructor
public class WxCpLoginVo implements Serializable {
/**
* 用户名
*/
@ApiModelProperty("用户名")
private String userName;
/**
* rsa密码
*/
@ApiModelProperty("rsa密码")
private String rsaPassword;
}

View File

@ -27,6 +27,11 @@ public class WxCpProperties {
*/
private String oAuth2RedirectUri;
/**
* o2认证注册到oam中的地址
*/
private String oAuth2registerUrl;
private List<AppConfig> appConfigs;
@Getter

View File

@ -27,7 +27,7 @@ public class ChangeWechatSharingBo implements Serializable {
/**
* 是否开启分账
*/
@NotNull(message = "是否开启商城不能为空")
@ApiModelProperty(value = "是否开启商城",required = true)
private Boolean isOpenMall;
@NotNull(message = "是否开启分账不能为空")
@ApiModelProperty(value = "是否开启分账",required = true)
private Boolean isOpenSharing;
}

View File

@ -56,9 +56,9 @@ public class Brand extends BaseEntity implements Serializable {
private String backgroundUrl;
/**
* 是否开通商城
* 是否开通分账
*/
private Boolean isOpenMall;
private Boolean isOpenSharing;
/**
* 逻辑删除0否1是

View File

@ -152,7 +152,7 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
return this.mapper.paginateAs(pageDomain.getPageNum(), pageDomain.getPageSize(),
QueryWrapper.create()
.select(BRAND.ID, BRAND.BRAND_NAME, BRAND.WX_MCH_ID, BRAND.CREATE_TIME, BRAND.BACKGROUND_URL, BRAND.IS_OPEN_MALL)
.select(BRAND.ID, BRAND.BRAND_NAME, BRAND.WX_MCH_ID, BRAND.CREATE_TIME, BRAND.BACKGROUND_URL, BRAND.IS_OPEN_SHARING)
.and(BRAND.BRAND_NAME.like(brandName)),
BrandPageVo.class);
}

View File

@ -85,7 +85,9 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
@Override
@Transactional(rollbackFor = Exception.class)
public void insertSysRole(RoleBo bo) {
LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
Role role = BeanUtils.mapToClass(bo, Role.class);
role.setUserType(loginUser.getUserType());
this.save(role);
//将菜单信息录入中间表
if (!bo.getMenuIds().isEmpty()) {

View File

@ -66,10 +66,10 @@ public class BrandPageVo implements Serializable {
private String backgroundUrl;
/**
* 是否开通商城
* 是否开通分账
*/
@ApiModelProperty("是否开通商城")
private Boolean isOpenMall;
@ApiModelProperty("是否开通分账")
private Boolean isOpenSharing;
/**
* 创建时间