feat(qywx): 新增企业微信API相关功能及响应类
- 新增NewsArticle、NewsMessageResponse、GetAuthInfoResult等响应类,用于处理企业微信API的返回数据 - 在QywxApiUtil中新增sendNewsMessage和getAuthInfo方法,支持发送图文消息和获取企业授权信息 - 在QywxController中新增getAuthInfo接口,用于获取企业授权信息 - 在ReturnApprovalApplicationService中更新商品库存逻辑,确保退货审批通过后更新商品库存
This commit is contained in:
parent
14b32f6d07
commit
2453b7bea7
|
@ -5,6 +5,8 @@ import com.agileboot.api.customize.async.QyAsyncTaskFactory;
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.common.utils.weixin.aes.WXBizMsgCrypt;
|
import com.agileboot.common.utils.weixin.aes.WXBizMsgCrypt;
|
||||||
|
import com.agileboot.domain.qywx.api.QywxApiUtil;
|
||||||
|
import com.agileboot.domain.qywx.api.response.GetAuthInfoResult;
|
||||||
import com.agileboot.domain.qywx.auth.AuthApplicationService;
|
import com.agileboot.domain.qywx.auth.AuthApplicationService;
|
||||||
import com.agileboot.domain.qywx.auth.command.AddAuthCommand;
|
import com.agileboot.domain.qywx.auth.command.AddAuthCommand;
|
||||||
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
||||||
|
@ -82,6 +84,16 @@ public class QywxController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getAuthInfo")
|
||||||
|
public GetAuthInfoResult getAuthInfo(@RequestParam String suiteAccessToken, @RequestParam String corpid, @RequestParam String permanentCode) {
|
||||||
|
try {
|
||||||
|
return QywxApiUtil.getAuthInfo(suiteAccessToken, corpid, permanentCode);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("getAuthInfo error", e);
|
||||||
|
throw new ApiException(ErrorCode.FAILED, "获取企业授权信息失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/callback/data")
|
@GetMapping("/callback/data")
|
||||||
public String validateDataCallback(@RequestParam String msg_signature,
|
public String validateDataCallback(@RequestParam String msg_signature,
|
||||||
@RequestParam String timestamp,
|
@RequestParam String timestamp,
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
package com.agileboot.api.customize.async;
|
package com.agileboot.api.customize.async;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.hutool.http.HttpRequest;
|
import cn.hutool.http.HttpRequest;
|
||||||
import cn.hutool.json.JSONObject;
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.agileboot.domain.qywx.auth.db.QyAuthService;
|
import com.agileboot.domain.qywx.api.response.GetAuthInfoResult;
|
||||||
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
||||||
import com.agileboot.domain.qywx.authCorpInfo.command.AddAuthCorpInfoCommand;
|
import com.agileboot.domain.qywx.authCorpInfo.command.AddAuthCorpInfoCommand;
|
||||||
import com.agileboot.domain.qywx.authCorpInfo.command.UpdateAuthCorpInfoCommand;
|
import com.agileboot.domain.qywx.authCorpInfo.command.UpdateAuthCorpInfoCommand;
|
||||||
import com.agileboot.domain.qywx.authCorpInfo.db.QyAuthCorpInfoService;
|
|
||||||
import com.agileboot.domain.qywx.template.TemplateApplicationService;
|
|
||||||
import com.agileboot.domain.qywx.template.db.QyTemplateEntity;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class QyAsyncTaskFactory {
|
public class QyAsyncTaskFactory {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.agileboot.domain.qywx.api;
|
package com.agileboot.domain.qywx.api;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
|
@ -11,12 +12,43 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class QywxApiUtil {
|
public class QywxApiUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送图文消息
|
||||||
|
* @param accessToken 接口调用凭证
|
||||||
|
* @param agentId 应用ID
|
||||||
|
* @param toUser 成员ID列表(多个用|分隔)
|
||||||
|
* @param articles 图文条目列表
|
||||||
|
* @return 消息发送结果
|
||||||
|
*/
|
||||||
|
public static NewsMessageResponse sendNewsMessage(String accessToken, Integer agentId, String toUser, List<NewsArticle> articles) {
|
||||||
|
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("touser", toUser);
|
||||||
|
params.put("msgtype", "news");
|
||||||
|
params.put("agentid", agentId);
|
||||||
|
params.put("news", Collections.singletonMap("articles", JSONUtil.parse(articles)));
|
||||||
|
|
||||||
|
String paramJson = JSONUtil.toJsonStr(params);
|
||||||
|
String response = HttpUtil.post(url, paramJson);
|
||||||
|
log.info("sendNewsMessage response: {}", response);
|
||||||
|
|
||||||
|
NewsMessageResponse result = JSONUtil.toBean(response, NewsMessageResponse.class);
|
||||||
|
if (result.getErrcode() != 0) {
|
||||||
|
throw new ApiException(ErrorCode.Internal.INTERNAL_ERROR,
|
||||||
|
String.format("发送图文消息失败: %s", result.getErrmsg()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取企业微信部门列表(简易信息)
|
* 获取企业微信部门列表(简易信息)
|
||||||
* @param access_token 企业微信接口调用凭证
|
* @param access_token 企业微信接口调用凭证
|
||||||
|
@ -125,5 +157,18 @@ public class QywxApiUtil {
|
||||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败");
|
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GetAuthInfoResult getAuthInfo(String suiteAccessToken, String corpid, String permanentCode) {
|
||||||
|
String url = "https://qyapi.weixin.qq.com/cgi-bin/service/v2/get_auth_info?suite_access_token="+suiteAccessToken;
|
||||||
|
|
||||||
|
Map<String, String> requestBody = new HashMap<String, String>();
|
||||||
|
requestBody.put("auth_corpid", corpid);
|
||||||
|
requestBody.put("permanent_code", permanentCode);
|
||||||
|
|
||||||
|
String response = HttpUtil.post(url, JSONUtil.toJsonStr(requestBody));
|
||||||
|
log.info("getAuthInfo response: {}", response);
|
||||||
|
|
||||||
|
return JSONUtil.toBean(response, GetAuthInfoResult.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.agileboot.api.customize.async;
|
package com.agileboot.domain.qywx.api.response;
|
||||||
|
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.agileboot.domain.qywx.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class NewsArticle {
|
||||||
|
/**
|
||||||
|
* 图文消息标题
|
||||||
|
* 必填:是
|
||||||
|
* 长度限制:不超过128个字符
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图文消息描述
|
||||||
|
* 必填:是
|
||||||
|
* 长度限制:不超过512个字符
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击后跳转的链接
|
||||||
|
* 必填:是
|
||||||
|
* 格式要求:包含协议头(http/https)
|
||||||
|
* 长度限制:不超过2048字节
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图文消息配图的url
|
||||||
|
* 必填:否
|
||||||
|
* 长度限制:不超过2048字节
|
||||||
|
*/
|
||||||
|
private String picurl;
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.agileboot.domain.qywx.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class NewsMessageResponse {
|
||||||
|
/**
|
||||||
|
* 返回码
|
||||||
|
* 0表示成功,非0表示失败
|
||||||
|
*/
|
||||||
|
private Integer errcode;
|
||||||
|
/**
|
||||||
|
* 错误信息
|
||||||
|
* 成功返回"ok"
|
||||||
|
*/
|
||||||
|
private String errmsg;
|
||||||
|
/**
|
||||||
|
* 不合法的userid列表
|
||||||
|
* 多个接收者用'|'分隔
|
||||||
|
*/
|
||||||
|
private String invaliduser;
|
||||||
|
/**
|
||||||
|
* 不合法的部门id列表
|
||||||
|
* 多个接收者用'|'分隔
|
||||||
|
*/
|
||||||
|
private String invalidparty;
|
||||||
|
/**
|
||||||
|
* 不合法的标签id列表
|
||||||
|
* 多个接收者用'|'分隔
|
||||||
|
*/
|
||||||
|
private String invalidtag;
|
||||||
|
/**
|
||||||
|
* 没有基础接口许可的userid列表
|
||||||
|
* 包含已过期的许可
|
||||||
|
*/
|
||||||
|
private String unlicenseduser;
|
||||||
|
/**
|
||||||
|
* 消息id
|
||||||
|
* 用于撤回应用消息(72小时内有效)
|
||||||
|
*/
|
||||||
|
private String msgid;
|
||||||
|
/**
|
||||||
|
* 响应代码
|
||||||
|
* 仅模板卡片消息返回,用于更新消息(72小时内有效)
|
||||||
|
*/
|
||||||
|
private String response_code;
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ import com.agileboot.domain.shop.approval.model.ReturnApprovalModel;
|
||||||
import com.agileboot.domain.shop.approval.model.ReturnApprovalModelFactory;
|
import com.agileboot.domain.shop.approval.model.ReturnApprovalModelFactory;
|
||||||
import com.agileboot.domain.shop.approval.query.SearchApiReturnApprovalQuery;
|
import com.agileboot.domain.shop.approval.query.SearchApiReturnApprovalQuery;
|
||||||
import com.agileboot.domain.shop.approval.query.SearchReturnApprovalQuery;
|
import com.agileboot.domain.shop.approval.query.SearchReturnApprovalQuery;
|
||||||
|
import com.agileboot.domain.shop.goods.model.GoodsModel;
|
||||||
|
import com.agileboot.domain.shop.goods.model.GoodsModelFactory;
|
||||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
||||||
import com.agileboot.domain.shop.order.model.OrderGoodsModel;
|
import com.agileboot.domain.shop.order.model.OrderGoodsModel;
|
||||||
import com.agileboot.domain.shop.order.model.OrderGoodsModelFactory;
|
import com.agileboot.domain.shop.order.model.OrderGoodsModelFactory;
|
||||||
|
@ -45,6 +47,7 @@ public class ReturnApprovalApplicationService {
|
||||||
private final OrderGoodsModelFactory orderGoodsModelFactory;
|
private final OrderGoodsModelFactory orderGoodsModelFactory;
|
||||||
private final OrderModelFactory orderModelFactory;
|
private final OrderModelFactory orderModelFactory;
|
||||||
private final PaymentApplicationService paymentApplicationService;
|
private final PaymentApplicationService paymentApplicationService;
|
||||||
|
private final GoodsModelFactory goodsModelFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取退货审批列表
|
* 获取退货审批列表
|
||||||
|
@ -137,6 +140,7 @@ public class ReturnApprovalApplicationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新审批状态为通过
|
||||||
model.validateApprovalStatus();
|
model.validateApprovalStatus();
|
||||||
model.setAuditImages(command.getAuditImages());
|
model.setAuditImages(command.getAuditImages());
|
||||||
model.setAuditRemark(command.getAuditRemark());
|
model.setAuditRemark(command.getAuditRemark());
|
||||||
|
@ -147,6 +151,11 @@ public class ReturnApprovalApplicationService {
|
||||||
// 更新关联订单商品状态
|
// 更新关联订单商品状态
|
||||||
orderGoodsModel.setStatus(2); // 6表示已完成退货
|
orderGoodsModel.setStatus(2); // 6表示已完成退货
|
||||||
orderGoodsModel.updateById();
|
orderGoodsModel.updateById();
|
||||||
|
|
||||||
|
// 更新商品库存
|
||||||
|
GoodsModel goodsModel = goodsModelFactory.loadById(orderGoodsModel.getGoodsId());
|
||||||
|
goodsModel.setStock(goodsModel.getStock() + orderGoodsModel.getQuantity());
|
||||||
|
goodsModel.updateById();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue