feat(企业微信): 添加逾期商品提醒功能
新增企业微信定时任务,每天检查逾期未归还商品并发送提醒 在用户服务中添加通过手机号查询用户的方法 修改未归还商品查询接口,支持按企业ID过滤
This commit is contained in:
parent
929b70897f
commit
2c7a336ae9
|
@ -1,6 +1,8 @@
|
|||
package com.agileboot.admin.controller.shop;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.constant.Constants;
|
||||
import com.agileboot.common.constant.WeixinConstants;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
|
@ -26,16 +28,10 @@ import java.math.BigDecimal;
|
|||
import java.util.List;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/shop/shops")
|
||||
|
@ -53,7 +49,10 @@ public class ShopController extends BaseController {
|
|||
@Operation(summary = "首页数据")
|
||||
@PreAuthorize("@permission.has('welcome:info')")
|
||||
@GetMapping("/Stats")
|
||||
public ResponseDTO<StatsDTO> stats() {
|
||||
public ResponseDTO<StatsDTO> stats(@RequestParam String corpid) {
|
||||
if (StringUtils.isBlank(corpid)) {
|
||||
corpid = WeixinConstants.corpid;
|
||||
}
|
||||
// 创建统计数据DTO对象
|
||||
StatsDTO statsDTO = new StatsDTO();
|
||||
// 设置商店总数(调用商店服务统计)
|
||||
|
@ -67,7 +66,7 @@ public class ShopController extends BaseController {
|
|||
// 设置订单总金额(调用订单服务计算)
|
||||
statsDTO.setOrderAmountSum(orderApplicationService.sumTotalAmount());
|
||||
|
||||
List<ShopOrderGoodsEntity> unReturnOrderGoods = orderApplicationService.selectUnReturnOrderGoods();
|
||||
List<ShopOrderGoodsEntity> unReturnOrderGoods = orderApplicationService.selectUnReturnOrderGoods(corpid);
|
||||
// 设置未还商品数量(调用订单服务统计)
|
||||
statsDTO.setUnReturnedGoodsCount((long) unReturnOrderGoods.size());
|
||||
// 设置未还订单数量(调用订单服务统计)
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
package com.agileboot.admin.customize.service.job;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.agileboot.domain.ab98.user.db.Ab98UserService;
|
||||
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.qywx.department.DepartmentApplicationService;
|
||||
import com.agileboot.domain.qywx.template.TemplateApplicationService;
|
||||
import com.agileboot.domain.qywx.template.command.UpdateTemplateCommand;
|
||||
import com.agileboot.domain.qywx.template.db.QyTemplateEntity;
|
||||
import com.agileboot.domain.qywx.user.QyUserApplicationService;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserEntity;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserService;
|
||||
import com.agileboot.domain.qywx.userQySys.SysUserQyUserApplicationService;
|
||||
import com.agileboot.domain.ab98.user.db.Ab98UserEntity;
|
||||
import com.agileboot.domain.shop.order.OrderApplicationService;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderEntity;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderService;
|
||||
import com.agileboot.domain.system.role.db.SysRoleService;
|
||||
import com.agileboot.domain.system.user.model.UserModelFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class QywxMessageJob {
|
||||
private final TemplateApplicationService templateApplicationService;
|
||||
private final AuthCorpInfoApplicationService authCorpInfoApplicationService;
|
||||
private final AccessTokenApplicationService accessTokenApplicationService;
|
||||
private final DepartmentApplicationService departmentApplicationService;
|
||||
private final QyUserApplicationService qyUserApplicationService;
|
||||
private final SysUserQyUserApplicationService sysUserQyUserApplicationService;
|
||||
private final UserModelFactory userModelFactory;
|
||||
private final SysRoleService sysRoleService;
|
||||
private final OrderApplicationService orderApplicationService;
|
||||
private final ShopOrderService orderService;
|
||||
private final Ab98UserService ab98UserService;
|
||||
private final QyUserService qyUserService;
|
||||
|
||||
// private static final String appid = "QYTONG_YS_WXSHOP";
|
||||
/**
|
||||
* 企业微信应用ID常量
|
||||
* 用于标识当前集成的第三方应用,对应企业微信服务商后台配置的应用凭证
|
||||
*/
|
||||
private static final String appid2 = "QWTONG_YS_WXSHOP";
|
||||
|
||||
/**
|
||||
* 每天向逾期未归还商品的用户发送提醒消息
|
||||
* 执行时间:每天凌晨2点
|
||||
*/
|
||||
@Scheduled(cron = "0 0 10 * * *")
|
||||
public void sendOverdueGoodsReminderTask() {
|
||||
try {
|
||||
// 1. 获取所有已授权企业信息
|
||||
List<QyAuthCorpInfoEntity> authCorpInfoList = authCorpInfoApplicationService.getByAppid(appid2);
|
||||
if (CollectionUtils.isEmpty(authCorpInfoList)) {
|
||||
log.info("没有找到已授权的企业信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 遍历企业处理
|
||||
for (QyAuthCorpInfoEntity authCorpInfo : authCorpInfoList) {
|
||||
sendOverdueReminderForCorp(appid2, authCorpInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送逾期商品提醒任务失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单个企业发送逾期提醒
|
||||
*/
|
||||
private void sendOverdueReminderForCorp(String appid, QyAuthCorpInfoEntity authCorpInfo) {
|
||||
try {
|
||||
// 3. 获取企业访问令牌
|
||||
QyAccessTokenEntity accessToken = accessTokenApplicationService.getByAppid(appid, authCorpInfo.getCorpid());
|
||||
if (accessToken == null || StringUtils.isBlank(accessToken.getAccessToken())) {
|
||||
log.error("企业[{}]获取accessToken失败", authCorpInfo.getCorpid());
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 查询逾期未归还商品记录(需实现商品借阅相关Service)
|
||||
List<ShopOrderGoodsEntity> unReturnOrderGoods = orderApplicationService.selectUnReturnOrderGoods(authCorpInfo.getCorpid());
|
||||
if (CollectionUtils.isEmpty(unReturnOrderGoods)) {
|
||||
log.info("企业[{}]没有未归还商品记录", authCorpInfo.getCorpid());
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. 筛选createTime超过一周的记录
|
||||
Date oneWeekAgo = DateUtil.offsetDay(new Date(), -7);
|
||||
List<ShopOrderGoodsEntity> overdueRecords = unReturnOrderGoods.stream()
|
||||
.filter(record -> record.getCreateTime().before(oneWeekAgo))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(overdueRecords)) {
|
||||
log.info("企业[{}]没有超过一周未归还的商品记录", authCorpInfo.getCorpid());
|
||||
return;
|
||||
}
|
||||
|
||||
// 6. 遍历逾期记录发送消息
|
||||
for (ShopOrderGoodsEntity record : overdueRecords) {
|
||||
sendSingleReminder(accessToken.getAccessToken(), authCorpInfo, record);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("企业[{}]发送逾期提醒失败", authCorpInfo.getCorpid(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送单个逾期提醒消息
|
||||
*/
|
||||
private void sendSingleReminder(String accessToken, QyAuthCorpInfoEntity authCorpInfo, ShopOrderGoodsEntity record) {
|
||||
try {
|
||||
ShopOrderEntity order = orderService.getById(record.getOrderId());
|
||||
if (order.getMode().equals(3) || order.getMode().equals(4)) {
|
||||
log.info("订单[{}]为租赁订单,无需发送逾期提醒", order.getOrderId());
|
||||
return;
|
||||
}
|
||||
// 6. 获取用户信息
|
||||
List<QyUserEntity> userList = qyUserApplicationService.getUserByUserId(order.getUserid());
|
||||
QyUserEntity user = null;
|
||||
if (CollectionUtils.isEmpty(userList)) {
|
||||
if (StringUtils.isBlank(order.getMobile())) {
|
||||
log.error("用户[{}]不存在企业微信信息", order.getName());
|
||||
return;
|
||||
}
|
||||
Ab98UserEntity ab98User = ab98UserService.selectByTel(order.getMobile());
|
||||
user = qyUserService.getUserByAb98UserId(ab98User.getAb98UserId(), authCorpInfo.getCorpid());
|
||||
} else {
|
||||
user = userList.get(0);
|
||||
}
|
||||
if (user == null || StringUtils.isBlank(user.getUserid())) {
|
||||
log.error("用户[{}]不存在企业微信信息", order.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
// 发送审核消息
|
||||
try {
|
||||
// 获取用户ID
|
||||
String toUser = user.getUserid();
|
||||
String toparty = "";
|
||||
String totag = "";
|
||||
List<NewsArticle> articles = new ArrayList<>();
|
||||
NewsArticle article = new NewsArticle();
|
||||
article.setTitle("耗材领用申请通知");
|
||||
article.setDescription("领用商品:" + record.getGoodsName());
|
||||
article.setDescription("你借用的 【" + record.getGoodsName() + "】 已逾期未归还,请及时归还");
|
||||
article.setPicurl(record.getCoverImg());
|
||||
article.setUrl("http://wxshop.ab98.cn/shop-api/api/shop/qy/wechatAuth/home");
|
||||
articles.add(article);
|
||||
|
||||
QywxApiUtil.sendNewsMessage(accessToken, Integer.valueOf(authCorpInfo.getAgentid()),
|
||||
toUser, toparty, totag, articles);
|
||||
} catch (Exception e) {
|
||||
log.error("发送退货审核通知失败", e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送单个逾期提醒失败", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,10 +39,13 @@ public interface Ab98UserMapper extends BaseMapper<Ab98UserEntity> {
|
|||
List<Ab98UserEntity> selectAllRegistered();
|
||||
|
||||
@Select("SELECT * FROM ab98_user WHERE userid = #{userid} LIMIT 1")
|
||||
Ab98UserEntity selectByUserid(String userid);
|
||||
Ab98UserEntity selectByUserid(@Param("userid")String userid);
|
||||
|
||||
@Select("SELECT * FROM ab98_user WHERE openid = #{openid} LIMIT 1")
|
||||
Ab98UserEntity selectByOpenid(String openid);
|
||||
Ab98UserEntity selectByOpenid(@Param("openid")String openid);
|
||||
|
||||
@Select("SELECT * FROM ab98_user WHERE tel = #{tel} LIMIT 1")
|
||||
Ab98UserEntity selectByTel(@Param("tel")String tel);
|
||||
|
||||
@Select("SELECT * FROM ab98_user WHERE openid = #{openid} AND userid = #{userid} LIMIT 1")
|
||||
Ab98UserEntity selectByOpenidAndUserid(@Param("openid")String openid, @Param("userid")String userid);
|
||||
|
|
|
@ -28,5 +28,7 @@ public interface Ab98UserService extends IService<Ab98UserEntity> {
|
|||
|
||||
Ab98UserEntity getByIdnum(String idnum);
|
||||
|
||||
Ab98UserEntity selectByTel(String tel);
|
||||
|
||||
Ab98UserEntity selectByOpenidAndUserid(String openid, String userid);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,11 @@ public class Ab98UserServiceImpl extends ServiceImpl<Ab98UserMapper, Ab98UserEnt
|
|||
return this.getOne(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ab98UserEntity selectByTel(String tel) {
|
||||
return baseMapper.selectByTel(tel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ab98UserEntity selectByOpenidAndUserid(String openid, String userid) {
|
||||
return baseMapper.selectByOpenidAndUserid(openid, userid);
|
||||
|
|
|
@ -545,7 +545,7 @@ public class OrderApplicationService {
|
|||
return orderService.sumTotalAmount();
|
||||
}
|
||||
|
||||
public List<ShopOrderGoodsEntity> selectUnReturnOrderGoods() {
|
||||
return orderGoodsService.selectUnReturnOrderGoods();
|
||||
public List<ShopOrderGoodsEntity> selectUnReturnOrderGoods(String corpid) {
|
||||
return orderGoodsService.selectUnReturnOrderGoods(corpid);
|
||||
}
|
||||
}
|
|
@ -46,9 +46,9 @@ public interface ShopOrderGoodsMapper extends BaseMapper<ShopOrderGoodsEntity> {
|
|||
"FROM shop_order_goods og " +
|
||||
"LEFT JOIN shop_goods g ON og.goods_id = g.goods_id " +
|
||||
"LEFT JOIN cabinet_cell cc ON og.cell_id = cc.cell_id " +
|
||||
"WHERE og.status = 1 " +
|
||||
"WHERE og.corpid = #{corpid} AND og.status = 1 " +
|
||||
"AND og.deleted = 0 " +
|
||||
"AND g.deleted = 0 " +
|
||||
"AND cc.deleted = 0 AND cc.goods_id = og.goods_id")
|
||||
List<ShopOrderGoodsEntity> selectUnReturnOrderGoods();
|
||||
List<ShopOrderGoodsEntity> selectUnReturnOrderGoods(@Param("corpid") String corpid);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public interface ShopOrderGoodsService extends IService<ShopOrderGoodsEntity> {
|
|||
|
||||
List<TodayLatestOrderGoodsDTO> selectTodayLatestOrderGoods();
|
||||
|
||||
List<ShopOrderGoodsEntity> selectUnReturnOrderGoods();
|
||||
List<ShopOrderGoodsEntity> selectUnReturnOrderGoods(String corpid);
|
||||
|
||||
List<ShopOrderGoodsEntity> selectOrderGoodsByApprovalId(Long approvalId);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ public class ShopOrderGoodsServiceImpl extends ServiceImpl<ShopOrderGoodsMapper,
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ShopOrderGoodsEntity> selectUnReturnOrderGoods() {
|
||||
return baseMapper.selectUnReturnOrderGoods();
|
||||
public List<ShopOrderGoodsEntity> selectUnReturnOrderGoods(String corpid) {
|
||||
return baseMapper.selectUnReturnOrderGoods(corpid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue