Compare commits
2 Commits
14b32f6d07
...
8e6131c197
Author | SHA1 | Date |
---|---|---|
|
8e6131c197 | |
|
2453b7bea7 |
|
@ -9,8 +9,12 @@ import com.agileboot.domain.qywx.api.QywxApiUtil;
|
|||
import com.agileboot.domain.qywx.api.response.DepartmentInfoResponse;
|
||||
import com.agileboot.domain.qywx.api.response.DepartmentInfoResponse.Department;
|
||||
import com.agileboot.domain.qywx.api.response.DepartmentListResponse;
|
||||
import com.agileboot.domain.qywx.api.response.GetAuthInfoResult;
|
||||
import com.agileboot.domain.qywx.api.response.GetAuthInfoResult.Agent;
|
||||
import com.agileboot.domain.qywx.api.response.GetAuthInfoResult.AuthCorpInfo;
|
||||
import com.agileboot.domain.qywx.api.response.UserListResponse;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.command.UpdateAuthCorpInfoCommand;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.db.QyAuthCorpInfoEntity;
|
||||
import com.agileboot.domain.qywx.department.DepartmentApplicationService;
|
||||
import com.agileboot.domain.qywx.department.command.AddDepartmentCommand;
|
||||
|
@ -46,6 +50,15 @@ import org.springframework.beans.BeanUtils;
|
|||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 企业微信定时任务调度器
|
||||
* 包含以下核心功能:
|
||||
* 1. 定时获取企业微信应用凭证(suite_access_token)
|
||||
* 2. 定时刷新企业微信访问令牌(access_token)
|
||||
* 3. 定时同步企业微信组织架构到本地数据库
|
||||
* 4. 定时同步企业微信用户信息到本地数据库
|
||||
* 定时任务均采用每小时固定分钟数执行策略,避免接口调用过于频繁
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
|
@ -59,8 +72,25 @@ public class QywxScheduleJob {
|
|||
private final UserModelFactory userModelFactory;
|
||||
|
||||
// private static final String appid = "QYTONG_YS_WXSHOP";
|
||||
/**
|
||||
* 企业微信应用ID常量
|
||||
* 用于标识当前集成的第三方应用,对应企业微信服务商后台配置的应用凭证
|
||||
*/
|
||||
private static final String appid2 = "QWTONG_YS_WXSHOP";
|
||||
|
||||
/**
|
||||
* 定时获取第三方应用凭证(suite_access_token)
|
||||
* 功能说明:
|
||||
* 1. 每小时第10分钟执行一次
|
||||
* 2. 根据应用ID获取企业微信应用配置
|
||||
* 3. 调用企业微信API获取最新的suite_access_token
|
||||
* 4. 更新本地存储的凭证信息
|
||||
* 执行流程:
|
||||
* - 通过appid查询应用模板配置
|
||||
* - 使用suite_id、secret和suite_ticket获取新凭证
|
||||
* - 将新凭证更新至数据库
|
||||
* 异常处理:捕获并记录异常日志,保证任务继续执行
|
||||
*/
|
||||
@Scheduled(cron = "0 10 * * * *")
|
||||
public void getSuiteAccessTokenTask() {
|
||||
/*try {
|
||||
|
@ -97,6 +127,18 @@ public class QywxScheduleJob {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时刷新访问令牌(access_token)
|
||||
* 功能说明:
|
||||
* 1. 每小时第20分钟执行一次
|
||||
* 2. 遍历所有已授权企业
|
||||
* 3. 为每个企业获取新的access_token
|
||||
* 4. 更新本地存储的访问令牌
|
||||
* 关键参数:
|
||||
* - corpid:企业微信ID
|
||||
* - permanent_code:企业永久授权码
|
||||
* 安全机制:不同企业间凭证隔离存储
|
||||
*/
|
||||
@Scheduled(cron = "0 20 * * * *")
|
||||
public void getAccessTokenTask() {
|
||||
/*try {
|
||||
|
@ -133,6 +175,18 @@ public class QywxScheduleJob {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时同步组织架构信息
|
||||
* 功能说明:
|
||||
* 1. 每小时第30分钟执行一次
|
||||
* 2. 获取企业微信部门列表
|
||||
* 3. 对比本地数据库进行增量同步
|
||||
* 同步策略:
|
||||
* - 新增:企业微信存在但本地不存在的部门
|
||||
* - 更新:名称或父部门发生变化的部门
|
||||
* - 删除:本地存在但企业微信不存在的部门
|
||||
* 数据一致性:通过corpid保证多企业数据隔离
|
||||
*/
|
||||
@Scheduled(cron = "0 30 * * * *")
|
||||
public void syncDepartmentInfoTask() {
|
||||
/*try {
|
||||
|
@ -295,6 +349,18 @@ public class QywxScheduleJob {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时同步用户信息
|
||||
* 功能说明:
|
||||
* 1. 每小时第40分钟执行一次
|
||||
* 2. 按部门遍历企业微信用户
|
||||
* 3. 三向对比(本地/企业微信/部门)进行同步
|
||||
* 同步维度:
|
||||
* - 基础信息:姓名、手机、邮箱等
|
||||
* - 组织关系:所属部门、职位信息
|
||||
* - 状态变更:离职/禁用用户
|
||||
* 数据关联:通过userid保持用户唯一标识
|
||||
*/
|
||||
@Scheduled(cron = "0 40 * * * *")
|
||||
public void syncUserInfoTask() {
|
||||
/*try {
|
||||
|
@ -503,6 +569,91 @@ public class QywxScheduleJob {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 定时获取企业授权信息
|
||||
* 功能说明:
|
||||
* 1. 每小时第45分钟执行一次
|
||||
* 2. 通过永久授权码获取企业基本信息、应用权限及授权管理员列表
|
||||
* 3. 更新本地存储的授权企业信息
|
||||
* 关键参数:
|
||||
* - corpid:企业微信ID
|
||||
* - permanent_code:企业永久授权码
|
||||
* API对应关系:
|
||||
* - 企业微信「获取企业授权信息」接口
|
||||
* 异常处理:捕获并记录异常日志,保证任务继续执行
|
||||
*/
|
||||
@Scheduled(cron = "0 45 * * * *")
|
||||
public void getAuthInfoTask() {
|
||||
try {
|
||||
getAuthInfo(appid2);
|
||||
} catch (Exception e) {
|
||||
log.error("getAuthInfoTask error appid: " + appid2, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void getAuthInfo(String appid) {
|
||||
log.info("getAuthInfo Current Thread : {}, Fixed Rate Task : The time is now {}",
|
||||
Thread.currentThread().getName(), DateUtil.formatTime(new Date()));
|
||||
|
||||
try {
|
||||
List<QyAuthCorpInfoEntity> authCorpInfoList = authCorpInfoApplicationService.getByAppid(appid);
|
||||
QyTemplateEntity template = templateApplicationService.getByAppid(appid);
|
||||
|
||||
if (template == null || authCorpInfoList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String suiteAccessToken = template.getSuiteAccessToken();
|
||||
if (StringUtils.isBlank(suiteAccessToken)) {
|
||||
log.error("getAuthInfo suiteAccessToken is null");
|
||||
return;
|
||||
}
|
||||
|
||||
for (QyAuthCorpInfoEntity authCorp : authCorpInfoList) {
|
||||
GetAuthInfoResult result = QywxApiUtil.getAuthInfo(suiteAccessToken,
|
||||
authCorp.getCorpid(), authCorp.getPermanentCode());
|
||||
|
||||
if (result.getErrcode() == 0) {
|
||||
Agent agent = result.getAuth_info().getAgent().get(0);
|
||||
AuthCorpInfo authCorpInfo = result.getAuth_corp_info();
|
||||
|
||||
UpdateAuthCorpInfoCommand command = new UpdateAuthCorpInfoCommand();
|
||||
command.setId(authCorp.getId());
|
||||
command.setCorpType(authCorpInfo.getCorp_type());
|
||||
command.setCorpSquareLogoUrl(authCorpInfo.getCorp_square_logo_url());
|
||||
command.setCorpUserMax(String.valueOf(authCorpInfo.getCorp_user_max()));
|
||||
command.setCorpFullName(authCorpInfo.getCorp_full_name());
|
||||
command.setSubjectType(String.valueOf(authCorpInfo.getSubject_type()));
|
||||
command.setVerifiedEndTime(String.valueOf(authCorpInfo.getVerified_end_time()));
|
||||
command.setCorpScale(authCorpInfo.getCorp_scale());
|
||||
command.setCorpIndustry(authCorpInfo.getCorp_industry());
|
||||
command.setCorpSubIndustry(authCorpInfo.getCorp_sub_industry());
|
||||
|
||||
command.setAgentid(String.valueOf(agent.getAgentid()));
|
||||
command.setAgentname(agent.getName());
|
||||
|
||||
authCorpInfoApplicationService.updateAuthCorpInfo(command);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("getAuthInfo error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时同步用户绑定关系
|
||||
* 功能说明:
|
||||
* 1. 每小时第50分钟执行一次
|
||||
* 2. 根据企业微信通讯录与本地用户数据匹配
|
||||
* 3. 维护系统用户与企业微信用户的映射关系
|
||||
* 同步维度:
|
||||
* - 用户状态变更(离职/禁用)
|
||||
* - 部门架构变动
|
||||
* - 系统账户匹配规则(手机号/邮箱)
|
||||
* 数据关联:通过userid与系统用户表建立外键关联
|
||||
* 异常处理:单个企业同步失败不影响其他企业执行
|
||||
*/
|
||||
@Scheduled(cron = "0 50 * * * *")
|
||||
public void syncUserBindingsTask() {
|
||||
try {
|
||||
|
|
|
@ -5,6 +5,8 @@ import com.agileboot.api.customize.async.QyAsyncTaskFactory;
|
|||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
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.command.AddAuthCommand;
|
||||
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")
|
||||
public String validateDataCallback(@RequestParam String msg_signature,
|
||||
@RequestParam String timestamp,
|
||||
|
|
|
@ -14,12 +14,15 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/shop")
|
||||
@CrossOrigin(origins = "*", allowedHeaders = "*")
|
||||
@RequiredArgsConstructor
|
||||
public class ShopController {
|
||||
|
||||
private final GoodsApplicationService goodsApplicationService;
|
||||
private final CategoryApplicationService categoryApplicationService;
|
||||
|
||||
|
@ -50,4 +53,33 @@ public class ShopController {
|
|||
+ "&state=STATE#wechat_redirect";
|
||||
return new RedirectView(authUrl);
|
||||
}
|
||||
|
||||
@GetMapping("/qy/wechatAuth")
|
||||
public RedirectView qyWechatAuthRedirect() {
|
||||
String authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
|
||||
+ "?appid=" + WeixinConstants.corpid
|
||||
+ "&redirect_uri=http%3A%2F%2Fwxshop.ab98.cn%2Fshop-api%2Fapi%2Fshop%2FapprovalRedirect"
|
||||
+ "&response_type=code"
|
||||
+ "&scope=snsapi_base"
|
||||
+ "&state=STATE"
|
||||
+ "&agentid=" + WeixinConstants.agentid
|
||||
+ "#wechat_redirect";
|
||||
return new RedirectView(authUrl);
|
||||
}
|
||||
|
||||
@GetMapping("/approvalRedirect")
|
||||
public RedirectView approvalRedirect(HttpServletRequest request) {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder
|
||||
.fromHttpUrl("http://wxshop.ab98.cn/shop#/approval/list")
|
||||
.queryParam("corpid", WeixinConstants.corpid)
|
||||
.queryParam("device", "APP");
|
||||
|
||||
request.getParameterMap().forEach((key, values) -> {
|
||||
if (!"corpid".equals(key) && !"device".equals(key)) {
|
||||
builder.queryParam(key, (Object[]) values);
|
||||
}
|
||||
});
|
||||
|
||||
return new RedirectView(builder.build().encode().toUriString());
|
||||
}
|
||||
}
|
|
@ -1,21 +1,16 @@
|
|||
package com.agileboot.api.customize.async;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONObject;
|
||||
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.command.AddAuthCorpInfoCommand;
|
||||
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.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
@Slf4j
|
||||
public class QyAsyncTaskFactory {
|
||||
|
|
|
@ -5,4 +5,6 @@ public class WeixinConstants {
|
|||
// public static String secret = "2a5a8b6ad3654a05f9fdd36524279a50";
|
||||
public static String appid = "wx9922dfbb0d4cd7bb";
|
||||
public static String secret = "7c7ef0dbb90b6be2abc8c269357f980a";
|
||||
public static String agentid = "1000231";
|
||||
public static String corpid = "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw";
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.agileboot.domain.qywx.api;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
|
@ -11,12 +12,45 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class QywxApiUtil {
|
||||
|
||||
/**
|
||||
* 发送图文消息
|
||||
* @param accessToken 接口调用凭证
|
||||
* @param agentId 应用ID
|
||||
* @param toUser 成员ID列表(多个用|分隔)
|
||||
* @param articles 图文条目列表
|
||||
* @return 消息发送结果
|
||||
*/
|
||||
public static NewsMessageResponse sendNewsMessage(String accessToken, Integer agentId, String toUser, String toparty, String totag, List<NewsArticle> articles) {
|
||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken + "&debug=" + 1;
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("touser", toUser);
|
||||
params.put("toparty", toparty);
|
||||
params.put("totag", totag);
|
||||
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 企业微信接口调用凭证
|
||||
|
@ -104,6 +138,14 @@ public class QywxApiUtil {
|
|||
return JSONUtil.toBean(response, OpenidResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过临时授权码获取企业微信用户ID
|
||||
*
|
||||
* @param accessToken 企业微信API访问凭证(需从企业微信后台获取)
|
||||
* @param code 用户授权后获取的临时授权码(通过OAuth2.0流程获取)
|
||||
* @return 企业微信用户的唯一标识userid
|
||||
* @throws ApiException 当请求失败或返回错误码时抛出异常
|
||||
*/
|
||||
public static String getQyUserid(String accessToken, String code) {
|
||||
try {
|
||||
String url = String.format(
|
||||
|
@ -125,5 +167,25 @@ public class QywxApiUtil {
|
|||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "微信服务调用失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业微信授权信息
|
||||
* @param suiteAccessToken 第三方应用凭证(从企业微信后台获取)
|
||||
* @param corpid 授权方企业微信ID
|
||||
* @param permanentCode 永久授权码(通过授权流程获取)
|
||||
* @return 包含企业授权信息的响应对象(包含agentid、权限集等信息)
|
||||
*/
|
||||
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 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;
|
||||
}
|
|
@ -3,6 +3,12 @@ package com.agileboot.domain.shop.approval;
|
|||
import com.agileboot.common.constant.PayApiConstants;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
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.NewsArticle;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.db.QyAuthCorpInfoEntity;
|
||||
import com.agileboot.domain.shop.approval.command.AddReturnApprovalCommand;
|
||||
import com.agileboot.domain.shop.approval.command.UpdateReturnApprovalCommand;
|
||||
import com.agileboot.domain.shop.approval.db.ReturnApprovalEntity;
|
||||
|
@ -12,6 +18,8 @@ import com.agileboot.domain.shop.approval.model.ReturnApprovalModel;
|
|||
import com.agileboot.domain.shop.approval.model.ReturnApprovalModelFactory;
|
||||
import com.agileboot.domain.shop.approval.query.SearchApiReturnApprovalQuery;
|
||||
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.model.OrderGoodsModel;
|
||||
import com.agileboot.domain.shop.order.model.OrderGoodsModelFactory;
|
||||
|
@ -23,6 +31,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -45,6 +54,9 @@ public class ReturnApprovalApplicationService {
|
|||
private final OrderGoodsModelFactory orderGoodsModelFactory;
|
||||
private final OrderModelFactory orderModelFactory;
|
||||
private final PaymentApplicationService paymentApplicationService;
|
||||
private final GoodsModelFactory goodsModelFactory;
|
||||
private final AuthCorpInfoApplicationService authCorpInfoApplicationService;
|
||||
private final AccessTokenApplicationService accessTokenApplicationService;
|
||||
|
||||
/**
|
||||
* 获取退货审批列表
|
||||
|
@ -137,6 +149,7 @@ public class ReturnApprovalApplicationService {
|
|||
}
|
||||
}
|
||||
|
||||
// 更新审批状态为通过
|
||||
model.validateApprovalStatus();
|
||||
model.setAuditImages(command.getAuditImages());
|
||||
model.setAuditRemark(command.getAuditRemark());
|
||||
|
@ -147,6 +160,11 @@ public class ReturnApprovalApplicationService {
|
|||
// 更新关联订单商品状态
|
||||
orderGoodsModel.setStatus(2); // 6表示已完成退货
|
||||
orderGoodsModel.updateById();
|
||||
|
||||
// 更新商品库存
|
||||
GoodsModel goodsModel = goodsModelFactory.loadById(orderGoodsModel.getGoodsId());
|
||||
goodsModel.setStock(goodsModel.getStock() + orderGoodsModel.getQuantity());
|
||||
goodsModel.updateById();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,6 +195,32 @@ public class ReturnApprovalApplicationService {
|
|||
orderGoodsModel.setStatus(5);
|
||||
orderGoodsModel.updateById();
|
||||
|
||||
// 发送审核消息
|
||||
try {
|
||||
String appid = "QWTONG_YS_WXSHOP";
|
||||
List<QyAuthCorpInfoEntity> authCorpInfoList = authCorpInfoApplicationService.getByAppid(appid);
|
||||
QyAuthCorpInfoEntity authCorpInfo = authCorpInfoList.stream()
|
||||
.filter(a -> "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw".equals(a.getCorpid()))
|
||||
.findFirst().orElse(null);
|
||||
QyAccessTokenEntity accessToken = accessTokenApplicationService.getByAppid(appid, authCorpInfo.getCorpid());
|
||||
// TODO 获取用户ID
|
||||
String toUser = "woZ1ZrEgAAV9AEdRt1MGQxSg-KDJrDlA|woZ1ZrEgAAoFQl9vWHMj4PkFoSc8FR8w";
|
||||
String toparty = "";
|
||||
String totag = "";
|
||||
List<NewsArticle> articles = new ArrayList<>();
|
||||
NewsArticle article = new NewsArticle();
|
||||
article.setTitle("退货审核通知");
|
||||
article.setDescription("退还商品:" + orderGoods.getGoodsName());
|
||||
article.setPicurl(orderGoods.getCoverImg());
|
||||
article.setUrl("http://wxshop.ab98.cn/shop-api/api/shop/qy/wechatAuth");
|
||||
articles.add(article);
|
||||
|
||||
QywxApiUtil.sendNewsMessage(accessToken.getAccessToken(), Integer.valueOf(authCorpInfo.getAgentid()),
|
||||
toUser, toparty, totag, articles);
|
||||
} catch (Exception e) {
|
||||
log.error("发送退货审核通知失败", e);
|
||||
}
|
||||
|
||||
return returnApprovalModel.selectById();
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue