系统用户关联企业微信用户
This commit is contained in:
parent
6f0e0587ab
commit
05f72a9a44
|
@ -107,14 +107,18 @@ public class QyDepartmentController extends BaseController {
|
|||
@GetMapping("/depts")
|
||||
public ResponseDTO<List<DeptDTO>> depts(@RequestParam String corpid) {
|
||||
List<QyDepartmentEntity> qyDepartmentEntityList = departmentApplicationService.getDepartmentList();
|
||||
if (StringUtils.isNoneBlank(corpid)) {
|
||||
qyDepartmentEntityList = qyDepartmentEntityList.stream()
|
||||
.filter(item -> StringUtils.equals(item.getCorpid(), corpid))
|
||||
.collect(Collectors.toList());
|
||||
if (StringUtils.isBlank(corpid)) {
|
||||
corpid = "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw";
|
||||
}
|
||||
// 根据corpid过滤部门列表
|
||||
String finalCorpid = corpid;
|
||||
qyDepartmentEntityList = qyDepartmentEntityList.stream()
|
||||
.filter(item -> StringUtils.equals(item.getCorpid(), finalCorpid))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<DeptDTO> deptList = qyDepartmentEntityList.stream().map(entity -> {
|
||||
DeptDTO dto = new DeptDTO(null); // 使用null初始化,后续手动设置字段
|
||||
dto.setId(entity.getId().longValue());
|
||||
dto.setId(Long.parseLong(entity.getDepartmentId()));
|
||||
dto.setParentId(Long.parseLong(entity.getParentid()));
|
||||
dto.setDeptName(entity.getName());
|
||||
dto.setOrderNum(0);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.agileboot.admin.controller.qywx;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.admin.customize.service.QywxScheduleJob;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
|
@ -7,6 +8,11 @@ import com.agileboot.common.core.dto.ResponseDTO;
|
|||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.qywx.accessToken.AccessTokenApplicationService;
|
||||
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
|
||||
import com.agileboot.domain.qywx.api.QywxApiUtil;
|
||||
import com.agileboot.domain.qywx.api.response.OpenidResponse;
|
||||
import com.agileboot.domain.qywx.api.response.UserIdResponse;
|
||||
import com.agileboot.domain.qywx.user.QyUserApplicationService;
|
||||
import com.agileboot.domain.qywx.user.command.AddQyUserCommand;
|
||||
import com.agileboot.domain.qywx.user.command.UpdateQyUserCommand;
|
||||
|
@ -35,6 +41,7 @@ public class QyUserController extends BaseController {
|
|||
|
||||
private final QyUserApplicationService qyUserApplicationService;
|
||||
private final QywxScheduleJob qywxScheduleJob;
|
||||
private final AccessTokenApplicationService accessTokenApplicationService;
|
||||
|
||||
@Operation(summary = "用户列表")
|
||||
@GetMapping
|
||||
|
@ -81,4 +88,17 @@ public class QyUserController extends BaseController {
|
|||
qywxScheduleJob.syncUserBindings();
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/convertToOpenid")
|
||||
public ResponseDTO<String> convertToOpenid(String corpid, String userid) {
|
||||
QyAccessTokenEntity accessToken = accessTokenApplicationService.getByAppid("QWTONG_YS_WXSHOP", corpid);
|
||||
OpenidResponse response = QywxApiUtil.convertToOpenid(accessToken.getAccessToken(), userid);
|
||||
return ResponseDTO.ok(JSONUtil.toJsonStr(response));
|
||||
}
|
||||
@GetMapping("/convertToUserid")
|
||||
public ResponseDTO<String> convertToUserid(String corpid, String openid) {
|
||||
QyAccessTokenEntity accessToken = accessTokenApplicationService.getByAppid("QWTONG_YS_WXSHOP", corpid);
|
||||
UserIdResponse response = QywxApiUtil.convertToUserid(accessToken.getAccessToken(), openid);
|
||||
return ResponseDTO.ok(JSONUtil.toJsonStr(response));
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ import cn.hutool.http.HttpUtil;
|
|||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants.Captcha;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
|
@ -94,41 +93,52 @@ public class LoginService {
|
|||
if (isCaptchaOn()) {
|
||||
validateCaptcha(loginCommand.getUsername(), loginCommand.getCaptchaCode(), loginCommand.getCaptchaCodeKey());
|
||||
}
|
||||
|
||||
// 用户验证
|
||||
Authentication authentication;
|
||||
|
||||
// 企业微信扫码登录分支
|
||||
if (StrUtil.isNotEmpty(loginCommand.getCode())) {
|
||||
String userid = getQyUserinfo(loginCommand.getCorpid(), loginCommand.getCode());
|
||||
String username = sysUserQyUserApplicationService.getUsernameByQyUserid(userid);
|
||||
// 通过企业微信code获取用户ID
|
||||
String userid = getQyUserid(loginCommand.getCorpid(), loginCommand.getCode());
|
||||
// 根据企业微信用户ID查询系统用户名
|
||||
SysUserEntity sysUserEntity = sysUserQyUserApplicationService.getSysUserByQyUserid(userid);
|
||||
|
||||
UserDetails user = fakeUserDetailsService.loadUserByUsername(username);
|
||||
// 加载用户信息并创建认证对象(跳过密码验证)
|
||||
UserDetails user = fakeUserDetailsService.loadUserByUsername(sysUserEntity.getUsername());
|
||||
authentication = new UsernamePasswordAuthenticationToken(
|
||||
user, null, user.getAuthorities());
|
||||
} else {
|
||||
// 普通账号密码登录分支
|
||||
String decryptPassword = decryptPassword(loginCommand.getPassword());
|
||||
try {
|
||||
// 该方法会去调用UserDetailsServiceImpl#loadUserByUsername 校验用户名和密码 认证鉴权
|
||||
// 调用认证管理器进行标准用户名密码认证
|
||||
// 内部会调用UserDetailsServiceImpl#loadUserByUsername
|
||||
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
|
||||
loginCommand.getUsername(), decryptPassword));
|
||||
} catch (BadCredentialsException e) {
|
||||
// 密码错误异常处理
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL,
|
||||
MessageUtils.message("Business.LOGIN_WRONG_USER_PASSWORD")));
|
||||
throw new ApiException(e, ErrorCode.Business.LOGIN_WRONG_USER_PASSWORD);
|
||||
} catch (AuthenticationException e) {
|
||||
// 认证通用异常处理
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL, e.getMessage()));
|
||||
throw new ApiException(e, ErrorCode.Business.LOGIN_ERROR, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
// 其他未知异常处理
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL, e.getMessage()));
|
||||
throw new ApiException(e, Business.LOGIN_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 把当前登录用户 放入上下文中
|
||||
// 将认证信息存入安全上下文
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
// 这里获取的loginUser是UserDetailsServiceImpl#loadUserByUsername方法返回的LoginUser
|
||||
// 从认证信息中获取系统登录用户对象
|
||||
SystemLoginUser loginUser = (SystemLoginUser) authentication.getPrincipal();
|
||||
// 记录登录成功信息
|
||||
recordLoginInfo(loginUser);
|
||||
// 生成token
|
||||
// 生成JWT令牌并缓存用户信息
|
||||
return tokenService.createTokenAndPutUserInCache(loginUser);
|
||||
}
|
||||
|
||||
|
@ -246,7 +256,7 @@ public class LoginService {
|
|||
return Convert.toBool(guavaCache.configCache.get(ConfigKeyEnum.CAPTCHA.getValue()));
|
||||
}
|
||||
|
||||
private String getQyUserinfo(String corpid, String code) {
|
||||
private String getQyUserid(String corpid, String code) {
|
||||
try {
|
||||
QyAccessTokenEntity qyAccessToken = accessTokenApplicationService.getByAppid("QWTONG_YS_WXSHOP", corpid);
|
||||
String url = String.format(
|
||||
|
|
|
@ -3,17 +3,25 @@ import cn.hutool.core.bean.BeanUtil;
|
|||
import cn.hutool.core.net.URLDecoder;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.api.response.GetBalanceResponse;
|
||||
import com.agileboot.common.constant.WeixinConstants;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Client;
|
||||
import com.agileboot.common.utils.OpenSignUtil;
|
||||
import com.agileboot.domain.qywx.accessToken.AccessTokenApplicationService;
|
||||
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
|
||||
import com.agileboot.domain.qywx.api.QywxApiUtil;
|
||||
import com.agileboot.domain.qywx.api.response.UserIdResponse;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.db.QyAuthCorpInfoEntity;
|
||||
import com.agileboot.domain.qywx.user.QyUserApplicationService;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserEntity;
|
||||
import com.agileboot.domain.shop.order.OrderApplicationService;
|
||||
import com.agileboot.domain.shop.payment.dto.PaymentCallbackRequest;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -37,6 +45,9 @@ import org.springframework.web.client.RestTemplate;
|
|||
@RequestMapping("/api/payment")
|
||||
public class PaymentController {
|
||||
private final OrderApplicationService orderApplicationService;
|
||||
private final AccessTokenApplicationService accessTokenApplicationService;
|
||||
private final QyUserApplicationService qyUserApplicationService;
|
||||
private final AuthCorpInfoApplicationService authCorpInfoApplicationService;
|
||||
|
||||
// 新增回调接口
|
||||
@PostMapping("/callback")
|
||||
|
@ -98,6 +109,48 @@ public class PaymentController {
|
|||
}
|
||||
}
|
||||
|
||||
@GetMapping("/getBalance")
|
||||
public ResponseDTO<GetBalanceResponse> getBalance(@RequestParam String openid) {
|
||||
String appid = "QWTONG_YS_WXSHOP";
|
||||
List<QyAuthCorpInfoEntity> qyAuthCorpInfoEntityList = authCorpInfoApplicationService.getByAppid(appid);
|
||||
List<QyUserEntity> qyUserEntityList = new ArrayList<>();
|
||||
for (QyAuthCorpInfoEntity qyAuthCorpInfoEntity : qyAuthCorpInfoEntityList) {
|
||||
String corpid = qyAuthCorpInfoEntity.getCorpid();
|
||||
QyAccessTokenEntity accessToken = accessTokenApplicationService.getByAppid(appid, corpid);
|
||||
UserIdResponse userIdResponse = QywxApiUtil.convertToUserid(accessToken.getAccessToken(), openid);
|
||||
QyUserEntity qyUser = qyUserApplicationService.getUserByUserId(userIdResponse.getUserid(), corpid);
|
||||
if (qyUser == null) {
|
||||
continue;
|
||||
}
|
||||
qyUserEntityList.add(qyUser);
|
||||
}
|
||||
if (qyUserEntityList.isEmpty()) {
|
||||
return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "无效的openid参数"));
|
||||
}
|
||||
// 找出余额最大的用户
|
||||
QyUserEntity maxBalanceUser = qyUserEntityList.stream()
|
||||
.filter(user -> user.getBalance() != null)
|
||||
.max(Comparator.comparing(QyUserEntity::getBalance))
|
||||
.orElse(null);
|
||||
|
||||
if (maxBalanceUser == null) {
|
||||
return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "未找到有效余额信息"));
|
||||
}
|
||||
|
||||
// 创建响应对象(假设GetBalanceResponse包含balance字段)
|
||||
GetBalanceResponse response = new GetBalanceResponse(maxBalanceUser.getUserid(), maxBalanceUser.getCorpid(), maxBalanceUser.getBalance());
|
||||
return ResponseDTO.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/getBalanceByQyUserid")
|
||||
public ResponseDTO<GetBalanceResponse> getBalanceByQyUserid(@RequestParam String corpid, @RequestParam String userid) {
|
||||
QyUserEntity qyUser = qyUserApplicationService.getUserByUserId(userid, corpid);
|
||||
|
||||
// 创建响应对象(假设GetBalanceResponse包含balance字段)
|
||||
GetBalanceResponse response = new GetBalanceResponse(qyUser.getUserid(), qyUser.getCorpid(), qyUser.getBalance());
|
||||
return ResponseDTO.ok(response);
|
||||
}
|
||||
|
||||
private PaymentCallbackRequest parseCallbackRequest(String requestBody) {
|
||||
// 实现将URL参数解析为PaymentCallbackRequest
|
||||
// 示例实现(需要根据实际参数格式调整):
|
||||
|
|
|
@ -1,27 +1,48 @@
|
|||
package com.agileboot.api.controller.common;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.api.customize.service.JwtTokenService;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.domain.common.dto.QyLoginDTO;
|
||||
import com.agileboot.domain.qywx.accessToken.AccessTokenApplicationService;
|
||||
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
|
||||
import com.agileboot.domain.qywx.api.QywxApiUtil;
|
||||
import com.agileboot.domain.qywx.api.response.OpenidResponse;
|
||||
import com.agileboot.domain.qywx.userQySys.SysUserQyUserApplicationService;
|
||||
import com.agileboot.domain.system.menu.MenuApplicationService;
|
||||
import com.agileboot.domain.system.menu.dto.RouterDTO;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.client.RestClientException;
|
||||
|
||||
/**
|
||||
* 调度日志操作处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/common")
|
||||
@AllArgsConstructor
|
||||
public class LoginController extends BaseController {
|
||||
|
||||
private final JwtTokenService jwtTokenService;
|
||||
private final AccessTokenApplicationService accessTokenApplicationService;
|
||||
private final SysUserQyUserApplicationService sysUserQyUserApplicationService;
|
||||
private final MenuApplicationService menuApplicationService;
|
||||
|
||||
/**
|
||||
* 访问首页,提示语
|
||||
|
@ -32,7 +53,34 @@ public class LoginController extends BaseController {
|
|||
return ResponseDTO.ok(token);
|
||||
}
|
||||
|
||||
@GetMapping("/login/qy")
|
||||
public ResponseDTO<QyLoginDTO> qyLogin(String corpid, String code, String state) {
|
||||
try {
|
||||
QyAccessTokenEntity qyAccessToken = accessTokenApplicationService.getByAppid("QWTONG_YS_WXSHOP", corpid);
|
||||
// 通过企业微信code获取用户ID
|
||||
String userid = QywxApiUtil.getQyUserid(qyAccessToken.getAccessToken(), code);
|
||||
// 根据企业微信用户ID查询系统用户名
|
||||
SysUserEntity sysUserEntity = sysUserQyUserApplicationService.getSysUserByQyUserid(userid);
|
||||
|
||||
SystemLoginUser loginUser = new SystemLoginUser();
|
||||
loginUser.setAdmin(false);
|
||||
loginUser.setUserId(sysUserEntity.getUserId());
|
||||
List<RouterDTO> routerTree = menuApplicationService.getRouterTree(loginUser);
|
||||
log.info("getRouterTree,userid: {}, routerTree: {}", userid, JSONUtil.toJsonStr(routerTree));
|
||||
|
||||
int isCabinetAdmin = 0;
|
||||
if (routerTree != null && !routerTree.isEmpty()) {
|
||||
isCabinetAdmin = routerTree.stream().anyMatch(router -> router.getName().equals("CabinetCell"))
|
||||
? 1 : 0;
|
||||
}
|
||||
|
||||
OpenidResponse openidResponse = QywxApiUtil.convertToOpenid(qyAccessToken.getAccessToken(), userid);
|
||||
|
||||
return ResponseDTO.ok(new QyLoginDTO(userid, openidResponse.getOpenid(), isCabinetAdmin));
|
||||
} catch (RestClientException e) {
|
||||
log.error("qyLogin失败", e);
|
||||
return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package com.agileboot.api.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class GetBalanceResponse {
|
||||
private String userid;
|
||||
private String corpid;
|
||||
private BigDecimal balance;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.agileboot.domain.common.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class QyLoginDTO {
|
||||
|
||||
private String userid;
|
||||
private String openid;
|
||||
private Integer isCabinetAdmin;
|
||||
}
|
|
@ -2,10 +2,17 @@ package com.agileboot.domain.qywx.api;
|
|||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
|
||||
import com.agileboot.domain.qywx.api.response.*;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class QywxApiUtil {
|
||||
|
@ -96,5 +103,27 @@ public class QywxApiUtil {
|
|||
|
||||
return JSONUtil.toBean(response, OpenidResponse.class);
|
||||
}
|
||||
|
||||
public static String getQyUserid(String accessToken, String code) {
|
||||
try {
|
||||
String url = String.format(
|
||||
"https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%s&code=%s",
|
||||
accessToken, code);
|
||||
|
||||
String response = HttpUtil.get(url);
|
||||
log.info("微信getuserinfo接口返回: {}", response);
|
||||
Map<String, Object> result = JSONUtil.toBean(response, HashMap.class);
|
||||
|
||||
if (result.containsKey("errcode") && !result.get("errcode").equals(0)) {
|
||||
log.error("微信接口返回错误: {}", result);
|
||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "无效的code参数");
|
||||
}
|
||||
|
||||
return String.valueOf(result.get("userid"));
|
||||
} catch (RestClientException e) {
|
||||
log.error("获取openid失败", e);
|
||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,4 +52,8 @@ public class QyUserApplicationService {
|
|||
model.deleteById();
|
||||
}
|
||||
}
|
||||
|
||||
public QyUserEntity getUserByUserId(String userid, String corpid) {
|
||||
return userService.getUserByUserId(userid, corpid);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
|
@ -142,6 +144,9 @@ public class QyUserEntity extends BaseEntity<QyUserEntity> {
|
|||
@TableField("cid")
|
||||
private Integer cid;
|
||||
|
||||
@ApiModelProperty("用户余额")
|
||||
@TableField("balance")
|
||||
private BigDecimal balance;
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
|
|||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
public interface QyUserMapper extends BaseMapper<QyUserEntity> {
|
||||
@Select("SELECT id, oper_id, open_userid, userid, name, mobile, department, user_order, position, gender, email, biz_mail, is_leader_in_dept, direct_leader, avatar, thumb_avatar, telephone, alias, extattr, status, qr_code, external_profile, external_position, address, main_department, enable, corpid, appid, cid " +
|
||||
@Select("SELECT * " +
|
||||
"FROM qy_user " +
|
||||
"${ew.customSqlSegment}")
|
||||
Page<QyUserEntity> getUserList(
|
||||
|
@ -22,4 +22,13 @@ public interface QyUserMapper extends BaseMapper<QyUserEntity> {
|
|||
"WHERE enable = '1' " +
|
||||
"ORDER BY oper_id DESC")
|
||||
List<QyUserEntity> selectAll();
|
||||
|
||||
@Select("SELECT * " +
|
||||
"FROM qy_user " +
|
||||
"WHERE userid = #{userid} " +
|
||||
"AND corpid = #{corpid}" +
|
||||
"AND enable = '1'" +
|
||||
"AND deleted = 0")
|
||||
QyUserEntity selectByUserid(@Param("userid") String userid, @Param("corpid") String corpid);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,4 +19,5 @@ public interface QyUserService extends IService<QyUserEntity> {
|
|||
|
||||
List<QyUserEntity> selectAll();
|
||||
|
||||
QyUserEntity getUserByUserId(String userid, String corpid);
|
||||
}
|
||||
|
|
|
@ -33,4 +33,9 @@ public class QyUserServiceImpl extends ServiceImpl<QyUserMapper, QyUserEntity> i
|
|||
|
||||
return this.list(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QyUserEntity getUserByUserId(String userid, String corpid) {
|
||||
return baseMapper.selectByUserid(userid, corpid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,12 @@ import com.agileboot.common.annotation.ExcelSheet;
|
|||
import com.agileboot.domain.common.cache.CacheCenter;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserEntity;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ExcelSheet(name = "企微用户信息列表")
|
||||
|
@ -96,4 +101,7 @@ public class QyUserDTO {
|
|||
|
||||
@ExcelColumn(name = "应用ID")
|
||||
private String appid;
|
||||
|
||||
@ExcelColumn(name = "用户余额")
|
||||
private BigDecimal balance;
|
||||
}
|
|
@ -11,10 +11,12 @@ import lombok.EqualsAndHashCode;
|
|||
@Data
|
||||
public class SearchQyUserQuery<T> extends AbstractPageQuery<T> {
|
||||
|
||||
private String corpid;
|
||||
private String userid;
|
||||
private String name;
|
||||
private String mobile;
|
||||
private String department;
|
||||
private String mainDepartment;
|
||||
private String enable;
|
||||
private Date startTime;
|
||||
private Date endTime;
|
||||
|
@ -24,11 +26,13 @@ public class SearchQyUserQuery<T> extends AbstractPageQuery<T> {
|
|||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
queryWrapper
|
||||
.eq(StrUtil.isNotEmpty(userid), "userid", userid)
|
||||
.like(StrUtil.isNotEmpty(name), "name", name)
|
||||
.like(StrUtil.isNotEmpty(mobile), "mobile", mobile)
|
||||
.eq(StrUtil.isNotEmpty(department), "department", department)
|
||||
.eq(StrUtil.isNotEmpty(enable), "enable", enable)
|
||||
.eq(StrUtil.isNotBlank(corpid), "corpid", corpid)
|
||||
.eq(StrUtil.isNotBlank(userid), "userid", userid)
|
||||
.like(StrUtil.isNotBlank(name), "name", name)
|
||||
.like(StrUtil.isNotBlank(mobile), "mobile", mobile)
|
||||
.eq(StrUtil.isNotBlank(department), "department", department)
|
||||
.eq(StrUtil.isNotBlank(mainDepartment), "main_department", mainDepartment)
|
||||
.eq(StrUtil.isNotBlank(enable), "enable", enable)
|
||||
.between(startTime != null && endTime != null, "create_time", startTime, endTime);
|
||||
|
||||
this.timeRangeColumn = "create_time";
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.agileboot.domain.qywx.userQySys.dto.SysUserQyUserDTO;
|
|||
import com.agileboot.domain.qywx.userQySys.model.SysUserQyUserModel;
|
||||
import com.agileboot.domain.qywx.userQySys.model.SysUserQyUserModelFactory;
|
||||
import com.agileboot.domain.qywx.userQySys.query.SearchSysUserQyUserQuery;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -63,7 +64,7 @@ public class SysUserQyUserApplicationService {
|
|||
return sysUserQyUserService.selectAll();
|
||||
}
|
||||
|
||||
public String getUsernameByQyUserid(String userid) {
|
||||
return sysUserQyUserService.getUsernameByQyUserid(userid);
|
||||
public SysUserEntity getSysUserByQyUserid(String userid) {
|
||||
return sysUserQyUserService.getSysUserByQyUserid(userid);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.agileboot.domain.qywx.userQySys.db;
|
||||
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
|
@ -39,11 +40,11 @@ public interface SysUserQyUserMapper extends BaseMapper<SysUserQyUserEntity> {
|
|||
@Select("SELECT * FROM sys_user_qy_user WHERE sys_user_id = #{sysUserId} AND qy_user_id = #{qyUserId} LIMIT 1")
|
||||
SysUserQyUserEntity selectBySysUserIdAndQyUserId(@Param("sysUserId") Long sysUserId, @Param("qyUserId") Integer qyUserId);
|
||||
|
||||
@Select("SELECT su.username " +
|
||||
@Select("SELECT su.* " +
|
||||
"FROM sys_user_qy_user suqy " +
|
||||
"JOIN qy_user qu ON suqy.qy_user_id = qu.id " +
|
||||
"JOIN sys_user su ON suqy.sys_user_id = su.user_id " +
|
||||
"WHERE qu.userid = #{userid}")
|
||||
String selectUsernameByQyUserid(@Param("userid") String userid);
|
||||
SysUserEntity selectSysUserByQyUserid(@Param("userid") String userid);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.agileboot.domain.qywx.userQySys.db;
|
||||
|
||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
|
@ -25,5 +26,5 @@ public interface SysUserQyUserService extends IService<SysUserQyUserEntity> {
|
|||
|
||||
SysUserQyUserEntity getBySysUserIdAndQyUserId(Long sysUserId, Integer qyUserId);
|
||||
|
||||
String getUsernameByQyUserid(String userid);
|
||||
SysUserEntity getSysUserByQyUserid(String userid);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.agileboot.domain.qywx.userQySys.db;
|
||||
|
||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
@ -46,7 +47,7 @@ public class SysUserQyUserServiceImpl extends ServiceImpl<SysUserQyUserMapper, S
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getUsernameByQyUserid(String userid) {
|
||||
return baseMapper.selectUsernameByQyUserid(userid);
|
||||
public SysUserEntity getSysUserByQyUserid(String userid) {
|
||||
return baseMapper.selectSysUserByQyUserid(userid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ import com.agileboot.domain.cabinet.smartCabinet.db.SmartCabinetEntity;
|
|||
import com.agileboot.domain.cabinet.smartCabinet.db.SmartCabinetService;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.mqtt.MqttService;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserEntity;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserService;
|
||||
import com.agileboot.domain.qywx.user.model.QyUserModelFactory;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsService;
|
||||
import com.agileboot.domain.shop.order.command.SubmitOrderCommand;
|
||||
|
@ -30,6 +33,7 @@ import java.math.BigDecimal;
|
|||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -50,6 +54,8 @@ public class OrderApplicationService {
|
|||
private final CabinetCellService cabinetCellService;
|
||||
private final SmartCabinetService smartCabinetService;
|
||||
private final MqttService mqttService;
|
||||
private final QyUserService userService;
|
||||
private final QyUserModelFactory qyUserModelFactory;
|
||||
|
||||
/*public PageDTO<ShopOrderDTO> getOrderList(SearchShopOrderQuery<> query) {
|
||||
Page<ShopOrderEntity> page = orderService.page(query.toPage(), query.toQueryWrapper());
|
||||
|
@ -122,12 +128,30 @@ public class OrderApplicationService {
|
|||
|
||||
processOrderGoods(orderModel, goodsList);
|
||||
|
||||
// 新增支付接口调用
|
||||
WxJsApiPreCreateRequest paymentRequest = buildPaymentRequest(orderModel);
|
||||
WxJsApiPreCreateResponse paymentResponse = paymentApplicationService.callJsApiPreCreate(paymentRequest);
|
||||
|
||||
return new CreateOrderResult(orderModel.getOrderId(), orderModel.getTotalAmount(), paymentResponse);
|
||||
if (Objects.equals(command.getPaymentType(), "wechat")) {
|
||||
// 新增支付接口调用
|
||||
WxJsApiPreCreateRequest paymentRequest = buildPaymentRequest(orderModel);
|
||||
WxJsApiPreCreateResponse paymentResponse = paymentApplicationService.callJsApiPreCreate(paymentRequest);
|
||||
|
||||
return new CreateOrderResult(orderModel.getOrderId(), orderModel.getTotalAmount(), paymentResponse, BigDecimal.valueOf(0));
|
||||
} else if (Objects.equals(command.getPaymentType(), "balance")) {
|
||||
QyUserEntity qyUser = userService.getUserByUserId(command.getUserid(), command.getCorpid());
|
||||
// 余额不足
|
||||
if (qyUser.getBalance().compareTo(orderModel.getTotalAmount()) < 0) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "余额不足");
|
||||
} else {
|
||||
qyUser.setBalance(qyUser.getBalance().subtract(orderModel.getTotalAmount()));
|
||||
userService.updateById(qyUser);
|
||||
}
|
||||
// 金额转换(元转分)并四舍五入
|
||||
BigDecimal amountInFen = orderModel.getTotalAmount()
|
||||
.multiply(new BigDecimal("100"))
|
||||
.setScale(0, RoundingMode.HALF_UP);
|
||||
handlePaymentSuccess(orderModel.getOrderId(), Integer.valueOf(amountInFen.toPlainString()),
|
||||
"balance-" + orderModel.getOrderId(), DateUtil.formatDateTime(new Date()));
|
||||
return new CreateOrderResult(orderModel.getOrderId(), orderModel.getTotalAmount(), null, qyUser.getBalance());
|
||||
}
|
||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "无效的支付类型");
|
||||
}
|
||||
|
||||
private WxJsApiPreCreateRequest buildPaymentRequest(OrderModel orderModel) {
|
||||
|
|
|
@ -8,6 +8,10 @@ import lombok.Data;
|
|||
@Data
|
||||
public class SubmitOrderCommand {
|
||||
private String openid;
|
||||
private String userid;
|
||||
private String corpid;
|
||||
private ShopOrderEntity order;
|
||||
// 支付类型'wechat' | 'balance'
|
||||
private String paymentType;
|
||||
private List<ShopOrderGoodsEntity> goodsList;
|
||||
}
|
|
@ -11,4 +11,5 @@ public class CreateOrderResult {
|
|||
private Long orderId;
|
||||
private BigDecimal totalAmount;
|
||||
private WxJsApiPreCreateResponse paymentInfo;
|
||||
private BigDecimal newBalance;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.agileboot.domain.system.dept.dto;
|
||||
|
||||
import com.agileboot.common.annotation.ExcelColumn;
|
||||
import com.agileboot.common.enums.common.StatusEnum;
|
||||
import com.agileboot.common.enums.BasicEnumUtil;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
||||
|
|
|
@ -14,4 +14,7 @@ CREATE TABLE `sys_user_qy_user` (
|
|||
KEY `idx_qy_user_id` (`qy_user_id`),
|
||||
CONSTRAINT `fk_sys_user_qy_user_sys` FOREIGN KEY (`sys_user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_sys_user_qy_user_qy` FOREIGN KEY (`qy_user_id`) REFERENCES `qy_user` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统用户与企业微信用户关联表';
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统用户与企业微信用户关联表';
|
||||
|
||||
ALTER TABLE qy_user
|
||||
ADD COLUMN `balance` DECIMAL(15,2) NOT NULL DEFAULT 0.00 COMMENT '用户余额(精度与商品价格对齐)';
|
Loading…
Reference in New Issue