Browse Source

Merge remote-tracking branch 'origin/master'

纪新园 3 days ago
parent
commit
358160cd9a
27 changed files with 638 additions and 73 deletions
  1. 36 0
      blade-common/src/main/java/org/springblade/common/enums/AppPushPathEnum.java
  2. 5 0
      blade-common/src/main/java/org/springblade/common/enums/CommonEnum.java
  3. 11 0
      blade-common/src/main/java/org/springblade/common/enums/NumberEnum.java
  4. 32 0
      blade-service-api/blade-payment-api/src/main/java/org/springblade/pay/tonglianPayment/vo/PushAppMsgVo.java
  5. 12 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/feign/IPJOrderClient.java
  6. 59 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/push/dto/AppMsgPushDto.java
  7. 90 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/push/entity/UserPushCid.java
  8. 20 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/push/vo/PushUserVo.java
  9. 12 8
      blade-service/blade-client/src/main/java/org/springblade/client/message/controller/MessageController.java
  10. 17 0
      blade-service/blade-pay/src/main/java/org/springblade/pay/tonglianPayment/service/impl/PaymentServiceImpl.java
  11. 2 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/enums/FinalMap.java
  12. 18 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/feign/PJOrderClient.java
  13. 1 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/mapper/OrderMapper.xml
  14. 3 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/service/impl/OrderServiceImpl.java
  15. 43 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/controller/UserPushCidController.java
  16. 10 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/mapper/UserPushCidMapper.java
  17. 8 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/mapper/UserPushCidMapper.xml
  18. 17 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/service/IUserPushCidService.java
  19. 44 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/service/impl/UserPushCidServiceImpl.java
  20. 65 59
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/ship/service/impl/ShipServiceImpl.java
  21. 127 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/util/PushUtil.java
  22. 1 1
      blade-service/blade-sales-part/src/main/resources/log/logback-dev.xml
  23. 1 1
      blade-service/blade-sales-part/src/main/resources/log/logback-prod.xml
  24. 1 1
      blade-service/blade-sales-part/src/main/resources/log/logback-test.xml
  25. 1 1
      blade-service/blade-user/src/main/resources/log/logback-dev.xml
  26. 1 1
      blade-service/blade-user/src/main/resources/log/logback-prod.xml
  27. 1 1
      blade-service/blade-user/src/main/resources/log/logback-test.xml

+ 36 - 0
blade-common/src/main/java/org/springblade/common/enums/AppPushPathEnum.java

@@ -0,0 +1,36 @@
+package org.springblade.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * @author Rain
+ */
+@Getter
+@AllArgsConstructor
+public enum AppPushPathEnum {
+
+	/**
+	 * 下单通知
+	 * 传输参数  id(订单id)、corpId(客户id)
+	 */
+	ORDER_NOTIFICATION("下单通知", "/pages/views/salesSlip/salesOrderDetails"),
+
+	/**
+	 * 出库通知
+	 * 传输参数  id(订单id)
+	 */
+	WAREHOUSE_DELIVERY_NOTIFICATION("出库通知", "/pages/views/warehouseDelivery/salesOrderDetails");
+
+	/**
+	 * 标题
+	 */
+	public final String title;
+
+	/**
+	 * 路径
+	 */
+	public final String path;
+
+}

+ 5 - 0
blade-common/src/main/java/org/springblade/common/enums/CommonEnum.java

@@ -83,6 +83,11 @@ public enum CommonEnum {
 	 */
 	GET_DATA_FAIL("获取数据失败"),
 
+	/**
+	 * 下单通知内容
+	 */
+	ORDER_CONTENT_MSG("订单号:%s\n客户名:%s\n业务员:%s\n订单信息:%s"),
+
 
 	/**
 	 * 中文分隔符号

+ 11 - 0
blade-common/src/main/java/org/springblade/common/enums/NumberEnum.java

@@ -71,6 +71,17 @@ public enum NumberEnum {
 	 */
 	FIFTEEN(15),
 
+
+	/**
+	 * 20
+	 */
+	TWENTY(20),
+
+	/**
+	 * 50
+	 */
+	FIFTY(50),
+
 	/**
 	 * 500
 	 */

+ 32 - 0
blade-service-api/blade-payment-api/src/main/java/org/springblade/pay/tonglianPayment/vo/PushAppMsgVo.java

@@ -0,0 +1,32 @@
+package org.springblade.pay.tonglianPayment.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Rain
+ */
+@Data
+public class PushAppMsgVo {
+
+
+	private List<Long> userIdList;
+
+
+	/**
+	 * 推送的标题
+	 * 注意:最多二十个字符
+	 */
+	private String title;
+
+	/**
+	 * 推送的内容
+	 * 注意:最多五十个字符
+	 * 换行使用换行符 \n
+	 */
+	private String content;
+
+	private Long orderId;
+
+}

+ 12 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/feign/IPJOrderClient.java

@@ -1,6 +1,7 @@
 package org.springblade.salesPart.feign;
 
 import org.springblade.core.tool.api.R;
+import org.springblade.pay.tonglianPayment.vo.PushAppMsgVo;
 import org.springblade.salesPart.entity.PjOrder;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -34,6 +35,8 @@ public interface IPJOrderClient {
 	String UNDER_REVIEW_RW = API_PREFIX + "/underReviewRW";
 	String PASS_CANCEL_RW = API_PREFIX + "/passCancelRW";
 
+	String PUSH_APP_MSG = API_PREFIX + "/pushAppMsg";
+
 
 	/**
 	 * 修改订单
@@ -133,4 +136,13 @@ public interface IPJOrderClient {
 	 */
 	@PostMapping(PASS_CANCEL_RW)
 	R passCancelRW(@RequestParam("id") Long id);
+
+
+	/**
+	 * 推送app 消息
+	 *
+	 * @param pushAppMsgVo 推送数据
+	 */
+	@PostMapping(PUSH_APP_MSG)
+	void pushAppMsg(@RequestBody PushAppMsgVo pushAppMsgVo);
 }

+ 59 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/push/dto/AppMsgPushDto.java

@@ -0,0 +1,59 @@
+package org.springblade.salesPart.push.dto;
+
+import lombok.Data;
+
+/**
+ * @author Rain
+ */
+@Data
+public class AppMsgPushDto {
+
+	/**
+	 * 请求id
+	 * 必须唯一
+	 */
+	private String requestId;
+
+	/**
+	 * 推送的id
+	 * 可为数组
+	 */
+	private String cId;
+
+	/**
+	 * 推送的标题
+	 * 注意:最多二十个字符
+	 */
+	private String title;
+
+	/**
+	 * 推送的内容
+	 * 注意:最多五十个字符
+	 * 换行使用换行符 \n
+	 */
+	private String content;
+
+	/**
+	 * 推送的附加信息
+	 */
+	private String payload;
+
+	/**
+	 * 是否是测试环境
+	 * true 为测试环境
+	 */
+	private boolean isDev;
+
+	/**
+	 * 跳转页面路径
+	 */
+	private String pagePath;
+
+	/**
+	 * 页面跳转参数
+	 * 注意:必须为json字符串,框架自带id必须转为字符串类型
+	 */
+	private String pageQuery;
+
+
+}

+ 90 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/push/entity/UserPushCid.java

@@ -0,0 +1,90 @@
+package org.springblade.salesPart.push.entity;
+
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 用户推送设备信息实体类
+ * 对应数据库表:user_push_cid
+ *
+ * @author Rain
+ */
+@Data
+public class UserPushCid {
+
+	/**
+	 * 主键ID
+	 */
+	private Long id;
+
+	/**
+	 * 租户ID
+	 */
+	private String tenantId;
+
+	/**
+	 * 用户ID(可以是系统用户ID、OpenID等)
+	 */
+	private Long userId;
+
+	/**
+	 * 推送客户端ID(Client ID)
+	 */
+	@NotBlank(message = "推送客户端ID不能为空")
+	@NotNull(message = "推送客户端ID不能为空")
+	private String cid;
+
+	/**
+	 * 应用ID(可区分多个应用)
+	 */
+	private String appId;
+
+	/**
+	 * 平台:android/ios/web
+	 */
+	private String platform;
+
+	/**
+	 * 设备品牌:huawei/xiaomi/oppo/vivo等
+	 */
+	private String deviceBrand;
+
+	/**
+	 * 设备型号
+	 */
+	private String deviceModel;
+
+	/**
+	 * 操作系统版本
+	 */
+	private String osVersion;
+
+	/**
+	 * 应用版本号
+	 */
+	private String appVersion;
+
+	/**
+	 * 状态:1-有效,0-无效
+	 */
+	private Integer status;
+
+	/**
+	 * 最后活跃时间
+	 */
+	private Date lastActiveTime;
+
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+
+	/**
+	 * 更新时间
+	 */
+	private Date updateTime;
+}

+ 20 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/push/vo/PushUserVo.java

@@ -0,0 +1,20 @@
+package org.springblade.salesPart.push.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author Rain
+ */
+@Data
+@AllArgsConstructor
+public class PushUserVo {
+
+
+	private Long userId;
+
+
+	private String userName;
+
+
+}

+ 12 - 8
blade-service/blade-client/src/main/java/org/springblade/client/message/controller/MessageController.java

@@ -32,6 +32,7 @@ import org.springblade.client.vo.MessageVO;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
@@ -40,6 +41,7 @@ import org.springframework.web.bind.annotation.*;
 import javax.validation.Valid;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 控制器
@@ -186,18 +188,20 @@ public class MessageController extends BladeController {
 	@ApiOperationSupport(order = 4)
 	@ApiOperation(value = "新增", notes = "传入message")
 	public R saveList(@Valid @RequestBody List<Message> messageList) {
-		for (Message message :messageList){
-			if (message.getUserId() == null) {
-				message.setUserId(AuthUtil.getUserId());
+		BladeUser msgUser = AuthUtil.getUser();
+		Date nowDate = new Date();
+		for (Message message : messageList){
+			if (Objects.isNull(message.getUserId())) {
+				message.setUserId(msgUser.getUserId());
 			}
 			if (StringUtils.isBlank(message.getUserName())) {
-				message.setUserName(AuthUtil.getUserName());
+				message.setUserName(msgUser.getUserName());
 			}
-			if (ObjectUtils.isNull(message.getTenantId())){
-				message.setTenantId(AuthUtil.getTenantId());
+			if (StringUtils.isBlank(message.getTenantId())){
+				message.setTenantId(msgUser.getTenantId());
 			}
-			message.setCreateTime(new Date());
-			message.setCreateUser(AuthUtil.getUserId());
+			message.setCreateTime(nowDate);
+			message.setCreateUser(msgUser.getUserId());
 		}
 		return R.status(messageService.saveBatch(messageList));
 	}

+ 17 - 0
blade-service/blade-pay/src/main/java/org/springblade/pay/tonglianPayment/service/impl/PaymentServiceImpl.java

@@ -10,6 +10,8 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import org.jetbrains.annotations.NotNull;
 import org.springblade.client.entity.*;
 import org.springblade.client.feign.*;
+import org.springblade.common.enums.AppPushPathEnum;
+import org.springblade.common.enums.CommonEnum;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
@@ -25,6 +27,7 @@ import org.springblade.pay.tonglianPayment.service.IWechatMarkService;
 import org.springblade.pay.tonglianPayment.utils.AnalysisMapUtils;
 import org.springblade.pay.tonglianPayment.utils.SybPayService;
 import org.springblade.pay.tonglianPayment.utils.SybUtil;
+import org.springblade.pay.tonglianPayment.vo.PushAppMsgVo;
 import org.springblade.purchase.sales.entity.Order;
 import org.springblade.purchase.sales.entity.OrderItems;
 import org.springblade.purchase.sales.feign.IOrderDescClient;
@@ -62,6 +65,7 @@ import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 /**
  * 标书代理信息表 服务实现类
@@ -944,6 +948,10 @@ public class PaymentServiceImpl implements IPaymentService {
 							DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 							String formatted = now.format(formatter);
 							//给角色为财务的人发送消息
+							PushAppMsgVo pushAppMsgVo = new PushAppMsgVo();
+							pushAppMsgVo.setTitle(AppPushPathEnum.ORDER_NOTIFICATION.title);
+							pushAppMsgVo.setContent(String.format(CommonEnum.ORDER_CONTENT_MSG.info, selectOrder.getOrdNo(), selectOrder.getCustomerName(), selectOrder.getSalerName(), "轮胎数量:" + selectOrder.getGoodsTotalNum() + ",轮胎金额:" + selectOrder.getTotalMoney()));
+							pushAppMsgVo.setOrderId(selectOrder.getId());
 							R<String> clientDeptIds = sysClient.getRoleIds(parametersDetails.getTenantId(), "客服");
 							if (clientDeptIds.isSuccess() && StringUtils.isNotBlank(clientDeptIds.getData())) {
 								String status = sysClient.paramServiceValue( parametersDetails.getTenantId(),"whether.branch.management");
@@ -980,6 +988,13 @@ public class PaymentServiceImpl implements IPaymentService {
 											throw new SecurityException("发送消息失败");
 										}
 									}
+									pushAppMsgVo.setUserIdList(userList.getData().stream().map(User::getId).collect(Collectors.toList()));
+									try {
+										ipjOrderClient.pushAppMsg(pushAppMsgVo);
+									} catch (Exception e) {
+										System.out.println("发送失败:" + e.getMessage());
+									}
+
 								}
 							}
 							if (ObjectUtils.isNotNull(selectOrder.getSalerId())) {
@@ -1002,6 +1017,8 @@ public class PaymentServiceImpl implements IPaymentService {
 								if (!save.isSuccess()) {
 									throw new SecurityException("发送消息失败");
 								}
+								pushAppMsgVo.setUserIdList(Collections.singletonList(selectOrder.getSalerId()));
+								ipjOrderClient.pushAppMsg(pushAppMsgVo);
 							}
 						}
 						if (useRecoveredBalance.compareTo(BigDecimal.ZERO) > 0) {

+ 2 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/enums/FinalMap.java

@@ -32,4 +32,6 @@ public class FinalMap {
 
 	public static final String GET_BY_ID = "getById";
 
+	public static final String APP_PUSH_URL = "https://push.echepei.com/pushAppMsg";
+
 }

+ 18 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/feign/PJOrderClient.java

@@ -5,10 +5,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springblade.common.enums.AppPushPathEnum;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.pay.tonglianPayment.vo.PushAppMsgVo;
 import org.springblade.salesPart.entity.PjOrder;
 import org.springblade.salesPart.entity.PjOrderItems;
 import org.springblade.salesPart.entity.PjProductLaunch;
@@ -16,7 +18,9 @@ import org.springblade.salesPart.feign.IPJOrderClient;
 import org.springblade.salesPart.order.service.IOrderItemsService;
 import org.springblade.salesPart.order.service.IOrderService;
 import org.springblade.salesPart.productLaunch.service.IProductLaunchService;
+import org.springblade.salesPart.push.dto.AppMsgPushDto;
 import org.springblade.salesPart.share.service.ISharePutOnShelvesService;
+import org.springblade.salesPart.util.PushUtil;
 import org.springblade.system.feign.ISysClient;
 import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.annotations.ApiIgnore;
@@ -42,6 +46,9 @@ public class PJOrderClient implements IPJOrderClient {
 
 	private final ISharePutOnShelvesService sharePutOnShelvesService;
 
+	private final PushUtil pushUtil;
+
+
 	@Override
 	public void updateOrder(List<PjOrder> order) {
 		orderService.updateBatchById(order);
@@ -178,4 +185,15 @@ public class PJOrderClient implements IPJOrderClient {
 	public R passCancelRW(Long id) {
 		return orderService.passCancelRW(id);
 	}
+
+	@Override
+	public void pushAppMsg(PushAppMsgVo pushAppMsgVo) {
+		AppMsgPushDto pushDto = new AppMsgPushDto();
+		pushDto.setTitle(pushAppMsgVo.getTitle());
+		pushDto.setContent(pushAppMsgVo.getContent());
+		pushDto.setPagePath(AppPushPathEnum.ORDER_NOTIFICATION.path);
+		pushDto.setPageQuery("{\"id\":\"" + pushAppMsgVo.getOrderId() + "\"}");
+		String result = pushUtil.sendAppTitleMsgByList(pushAppMsgVo.getUserIdList(), pushDto);
+		log.info("app推送返回:--" + result);
+	}
 }

+ 1 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/mapper/OrderMapper.xml

@@ -1047,6 +1047,7 @@
             pjpf_corps_desc pcd
                 LEFT JOIN pjpf_corps_addr pca ON pcd.id = pca.pid
                 AND pca.default_addres = '1'
+                AND pca.is_deleted = 0
                 AND pca.tenant_id = #{tenantId}
                 LEFT JOIN blade_user bu ON pcd.salesman_id = bu.id
                 inner JOIN (

+ 3 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/service/impl/OrderServiceImpl.java

@@ -5003,6 +5003,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, PjOrder> implemen
 		if (srcOrder.getIsDeleted().equals(NumberEnum.ONE.number)) {
 			return R.fail("订单已关闭");
 		}
+		if ("内部销售".equals(srcOrder.getBusinessSource())) {
+			return R.fail("该订单为客服创建订单,无法删除,请联系客服进行删除");
+		}
 		Date nowDate = new Date();
 		PjOrder updateOrder = new PjOrder();
 		updateOrder.setId(order.getId());

+ 43 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/controller/UserPushCidController.java

@@ -0,0 +1,43 @@
+package org.springblade.salesPart.push.controller;
+
+import lombok.AllArgsConstructor;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.salesPart.push.dto.AppMsgPushDto;
+import org.springblade.salesPart.push.entity.UserPushCid;
+import org.springblade.salesPart.push.service.IUserPushCidService;
+import org.springblade.salesPart.util.PushUtil;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * @author Rain
+ */
+@RestController
+@RequestMapping("/app/push")
+@AllArgsConstructor
+public class UserPushCidController {
+
+	private final IUserPushCidService userPushCidService;
+
+	private final PushUtil pushUtil;
+
+
+
+	@PostMapping("/saveUserCid")
+	public void saveUserCid(@RequestBody @Valid UserPushCid userPush) {
+		userPushCidService.saveUserCid(userPush);
+	}
+
+
+	@GetMapping("/testPush")
+	public R testPush() {
+		AppMsgPushDto pushDto = new AppMsgPushDto();
+		pushDto.setTitle("测试title--11");
+		pushDto.setContent("测试content--11");
+		return R.data(pushUtil.sendAppTitleMsgByOne(AuthUtil.getUserId(), pushDto));
+	}
+
+
+}

+ 10 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/mapper/UserPushCidMapper.java

@@ -0,0 +1,10 @@
+package org.springblade.salesPart.push.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.salesPart.push.entity.UserPushCid;
+
+/**
+ * @author Rain
+ */
+public interface UserPushCidMapper extends BaseMapper<UserPushCid> {
+}

+ 8 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/mapper/UserPushCidMapper.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--suppress ALL -->
+<mapper namespace="org.springblade.salesPart.push.mapper.UserPushCidMapper">
+
+
+
+</mapper>

+ 17 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/service/IUserPushCidService.java

@@ -0,0 +1,17 @@
+package org.springblade.salesPart.push.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.salesPart.push.entity.UserPushCid;
+
+/**
+ * @author Rain
+ */
+public interface IUserPushCidService extends IService<UserPushCid> {
+
+	/**
+	 * 保存用户推送设备信息
+	 *
+	 * @param userPush cid、platform、brand
+	 */
+	void saveUserCid(UserPushCid userPush);
+}

+ 44 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/push/service/impl/UserPushCidServiceImpl.java

@@ -0,0 +1,44 @@
+package org.springblade.salesPart.push.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.salesPart.push.entity.UserPushCid;
+import org.springblade.salesPart.push.mapper.UserPushCidMapper;
+import org.springblade.salesPart.push.service.IUserPushCidService;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * @author Rain
+ */
+@Service
+public class UserPushCidServiceImpl extends ServiceImpl<UserPushCidMapper, UserPushCid> implements IUserPushCidService {
+
+
+
+	@Override
+	public void saveUserCid(UserPushCid userPush) {
+		UserPushCid srcUserPush = baseMapper.selectOne(new LambdaQueryWrapper<UserPushCid>().eq(UserPushCid::getCid, userPush.getCid()).last("limit 1"));
+		if (Objects.nonNull(srcUserPush)) {
+			userPush.setId(srcUserPush.getId());
+			baseMapper.updateById(userPush);
+			return;
+		}
+		BladeUser saveUser = AuthUtil.getUser();
+		UserPushCid update = new UserPushCid();
+		update.setUpdateTime(new Date());
+		update.setStatus(0);
+		// 没有区分平台及品牌,后续需要就添加
+		baseMapper.update(update, new LambdaQueryWrapper<UserPushCid>().eq(UserPushCid::getUserId, saveUser.getUserId()));
+		userPush.setUserId(saveUser.getUserId());
+		userPush.setTenantId(saveUser.getTenantId());
+		baseMapper.insert(userPush);
+	}
+
+
+}

+ 65 - 59
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/ship/service/impl/ShipServiceImpl.java

@@ -17,7 +17,9 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import okhttp3.*;
 import org.springblade.client.entity.Message;
 import org.springblade.client.feign.IMessageClient;
+import org.springblade.common.enums.AppPushPathEnum;
 import org.springblade.common.enums.NumberEnum;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.jackson.JsonUtil;
@@ -46,6 +48,8 @@ import org.springblade.salesPart.order.mapper.OrderMapper;
 import org.springblade.salesPart.order.service.IOrderItemsService;
 import org.springblade.salesPart.order.service.IOrderRecordService;
 import org.springblade.salesPart.productLaunch.service.IProductLaunchService;
+import org.springblade.salesPart.push.dto.AppMsgPushDto;
+import org.springblade.salesPart.push.vo.PushUserVo;
 import org.springblade.salesPart.serial.service.IPjpfSerialService;
 import org.springblade.salesPart.share.service.ISharePutOnShelvesService;
 import org.springblade.salesPart.ship.mapper.ShipMapper;
@@ -60,6 +64,7 @@ import org.springblade.salesPart.storage.entity.ReservoirArea;
 import org.springblade.salesPart.storage.mapper.StorageDescMapper;
 import org.springblade.salesPart.storage.service.IReservoirAreaService;
 import org.springblade.salesPart.util.ParameterUtils;
+import org.springblade.salesPart.util.PushUtil;
 import org.springblade.salesPart.vo.OrderRecordVO;
 import org.springblade.salesPart.vo.ShipVO;
 import org.springblade.system.entity.Dept;
@@ -130,6 +135,8 @@ public class ShipServiceImpl extends ServiceImpl<ShipMapper, PjShip> implements
 
 	private final IReservoirAreaService reservoirAreaService;
 
+	private final PushUtil pushUtil;
+
 	/**
 	 * 获取收发货订单详情
 	 *
@@ -6739,9 +6746,10 @@ public class ShipServiceImpl extends ServiceImpl<ShipMapper, PjShip> implements
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public R outboundWorkOrderV1(String ids) {
+		BladeUser nowOutBoundWorkUser = AuthUtil.getUser();
 		List<Long> shipIds = Func.toLongList(ids);
 		List<PjShip> pjShipList = baseMapper.selectList(new LambdaQueryWrapper<PjShip>()
-			.eq(PjShip::getTenantId, AuthUtil.getTenantId())
+			.eq(PjShip::getTenantId, nowOutBoundWorkUser.getTenantId())
 			.eq(PjShip::getIsDeleted, 0)
 			.apply("find_in_set(id,'" + ids + "')"));
 		List<PjOrderItems> pjOrderItemsList = new ArrayList<>();
@@ -6755,13 +6763,13 @@ public class ShipServiceImpl extends ServiceImpl<ShipMapper, PjShip> implements
 				.in("pid", ordIds)
 				.eq("is_deleted", 0)
 				.apply("goods_num != send_num")
-				.eq("tenant_id", AuthUtil.getTenantId()));
+				.eq("tenant_id", nowOutBoundWorkUser.getTenantId()));
 		}
 		if (!pjOrderItemsList.isEmpty()) {
 			List<Long> goodsId = pjOrderItemsList.stream().map(PjOrderItems::getGoodsId).filter(Objects::nonNull).collect(Collectors.toList());
 			if (!goodsId.isEmpty() && !storageId.isEmpty()) {
 				stockDescList = iStockDescService.list(new LambdaQueryWrapper<PjStockDesc>()
-					.eq(PjStockDesc::getTenantId, AuthUtil.getTenantId())
+					.eq(PjStockDesc::getTenantId, nowOutBoundWorkUser.getTenantId())
 					.eq(PjStockDesc::getIsDeleted, 0)
 					.in(PjStockDesc::getGoodsId, goodsId)
 					.in(PjStockDesc::getStorageId, storageId));
@@ -6787,10 +6795,10 @@ public class ShipServiceImpl extends ServiceImpl<ShipMapper, PjShip> implements
 			gdShip.setId(null);
 			gdShip.setBillno(billNo);
 			gdShip.setStatusName(OrderTypeEnum.TOBESHIPPEDOUT.getType());
-			gdShip.setTenantId(AuthUtil.getTenantId());
+			gdShip.setTenantId(nowOutBoundWorkUser.getTenantId());
 			gdShip.setBizTypeName(OrderTypeEnum.FHGD.getType());
-			gdShip.setCreateDept(Long.valueOf(AuthUtil.getDeptId()));
-			gdShip.setCreateUser(AuthUtil.getUserId());
+			gdShip.setCreateDept(Long.valueOf(nowOutBoundWorkUser.getDeptId()));
+			gdShip.setCreateUser(nowOutBoundWorkUser.getUserId());
 			gdShip.setCreateTime(new Date());
 			gdShip.setTaskId(rwShip.getId());
 			gdShip.setSendTotalNum(new BigDecimal("0.00"));
@@ -6828,8 +6836,8 @@ public class ShipServiceImpl extends ServiceImpl<ShipMapper, PjShip> implements
 								shipItems.setPid(item.getId());
 								shipItems.setSrcItemId(e.getId());
 								shipItems.setCreateTime(new Date());
-								shipItems.setCreateUser(AuthUtil.getUserId());
-								shipItems.setCreateDept(Long.valueOf(AuthUtil.getDeptId()));
+								shipItems.setCreateUser(nowOutBoundWorkUser.getUserId());
+								shipItems.setCreateDept(Long.valueOf(nowOutBoundWorkUser.getDeptId()));
 								BigDecimal sendNum = e.getGoodsNum().subtract(e.getSendNum());
 								if (balanceQuantity.compareTo(sendNum) >= 0) {
 									shipItems.setSendNum(sendNum);
@@ -6861,61 +6869,59 @@ public class ShipServiceImpl extends ServiceImpl<ShipMapper, PjShip> implements
 			saveHistory(item.getId(), OrderTypeEnum.TOBESHIPPEDOUT.getType());
 
 			//给角色为派工的人发送消息
-			if (ObjectUtils.isNotNull(rwShip.getStockClerkId())) {
-				Message sendMessage = new Message();
-				sendMessage.setParameter(item.getId() + "");
-				sendMessage.setUserName(AuthUtil.getUserName());
-				sendMessage.setUserId(null);
-				sendMessage.setToUserId(rwShip.getStockClerkId());
-				sendMessage.setToUserName(rwShip.getStockClerkName());
-				sendMessage.setMessageType(1);
-				sendMessage.setTenantId(AuthUtil.getTenantId());
-				sendMessage.setCreateUser(null);
-				sendMessage.setCreateTime(new Date());
-				sendMessage.setUrl("/tirePartsMall/salesManagement/outboundWorkOrder/index");
-				sendMessage.setPageLabel("出库工单");
-				sendMessage.setPageStatus("this.$store.getters.domSaleStatus");
-				sendMessage.setMessageBody("您有新的出库工单请及时处理!单号:" + item.getBillno() + "时间:" + formatted);
-				R save = messageClient.save(sendMessage);
+			List<PushUserVo> sendMsgUserIds = new ArrayList<>();
+			send: if (ObjectUtils.isNotNull(rwShip.getStockClerkId())) {
+				sendMsgUserIds.add(new PushUserVo(rwShip.getStockClerkId(), rwShip.getStockClerkName()));
+			} else {
+				R<String> clientRoleIds = sysClient.getRoleIds(nowOutBoundWorkUser.getTenantId(), "库管");
+				if (!clientRoleIds.isSuccess() || StringUtils.isBlank(clientRoleIds.getData())) {
+					break send;
+				}
+				Long sendUserStorageId = null;
+				if (ParameterUtils.whetherDatabaseSharding()) {
+					sendUserStorageId = item.getStorageId();
+				}
+				R<List<User>> userList = userClient.listUserByRoleId(clientRoleIds.getData(), nowOutBoundWorkUser.getTenantId(),
+					item.getSalesCompanyId() + "", sendUserStorageId);
+				if (!userList.isSuccess() || CollectionUtils.isEmpty(userList.getData())) {
+					break send;
+				}
+				sendMsgUserIds = userList.getData().stream().map(usr -> new PushUserVo(usr.getId(), usr.getRealName())).collect(Collectors.toList());
+			}
+			if (CollectionUtils.isNotEmpty(sendMsgUserIds)) {
+				List<Message> sendMessageList = new ArrayList<>();
+				Date sendMsgDate = new Date();
+				String msgBody = "您有新的出库工单请及时处理!单号:" + item.getBillno() + "时间:" + formatted;
+				for (PushUserVo e : sendMsgUserIds) {
+					Message sendMessage = new Message();
+					sendMessageList.add(sendMessage);
+					sendMessage.setParameter(item.getId() + "");
+					sendMessage.setUserName(nowOutBoundWorkUser.getUserName());
+					sendMessage.setUserId(null);
+					sendMessage.setMessageType(1);
+					sendMessage.setTenantId(nowOutBoundWorkUser.getTenantId());
+					sendMessage.setCreateUser(null);
+					sendMessage.setCreateTime(sendMsgDate);
+					sendMessage.setUrl("/tirePartsMall/salesManagement/outboundWorkOrder/index");
+					sendMessage.setPageLabel("出库工单");
+					sendMessage.setPageStatus("this.$store.getters.domSaleStatus");
+					sendMessage.setMessageBody(msgBody);
+					sendMessage.setToUserId(e.getUserId());
+					sendMessage.setToUserName(e.getUserName());
+				}
+				R save = messageClient.saveList(sendMessageList);
 				System.out.println("发送结果:" + save);
+				// 不合理,消息的成功与否不应该影响主流程
 				if (!save.isSuccess()) {
 					throw new SecurityException("发送消息失败");
 				}
-			} else {
-				//给角色为派工的人发送消息
-				R<String> clientDeptIds = sysClient.getRoleIds(AuthUtil.getTenantId(), "库管");
-				if (clientDeptIds.isSuccess() && StringUtils.isNotBlank(clientDeptIds.getData())) {
-					Long storage_id = null;
-					if (ParameterUtils.whetherDatabaseSharding()) {
-						storage_id = item.getStorageId();
-					}
-					R<List<User>> userList = userClient.listUserByRoleId(clientDeptIds.getData(), AuthUtil.getTenantId(),
-						item.getSalesCompanyId() + "", storage_id);
-					if (userList.isSuccess() && CollectionUtils.isNotEmpty(userList.getData())) {
-						for (User datum : userList.getData()) {
-							//循环发送消息
-							Message sendMessage = new Message();
-							sendMessage.setParameter(item.getId() + "");
-							sendMessage.setUserName(AuthUtil.getUserName());
-							sendMessage.setUserId(null);
-							sendMessage.setToUserId(datum.getId());
-							sendMessage.setToUserName(datum.getName());
-							sendMessage.setMessageType(1);
-							sendMessage.setTenantId(AuthUtil.getTenantId());
-							sendMessage.setCreateUser(null);
-							sendMessage.setCreateTime(new Date());
-							sendMessage.setUrl("/tirePartsMall/salesManagement/outboundWorkOrder/index");
-							sendMessage.setPageLabel("出库工单");
-							sendMessage.setPageStatus("this.$store.getters.domSaleStatus");
-							sendMessage.setMessageBody("您有新的出库工单请及时处理!单号:" + item.getBillno() + "时间:" + formatted);
-							R save = messageClient.save(sendMessage);
-							System.out.println("发送结果:" + save);
-							if (!save.isSuccess()) {
-								throw new SecurityException("发送消息失败");
-							}
-						}
-					}
-				}
+				List<Long> userIds = sendMsgUserIds.stream().map(PushUserVo::getUserId).collect(Collectors.toList());
+				AppMsgPushDto pushDto = new AppMsgPushDto();
+				pushDto.setTitle(AppPushPathEnum.WAREHOUSE_DELIVERY_NOTIFICATION.title);
+				pushDto.setContent(msgBody);
+				pushDto.setPagePath(AppPushPathEnum.WAREHOUSE_DELIVERY_NOTIFICATION.path);
+				pushDto.setPageQuery("{\"id\":\"" + item.getId() + "\"}");
+				pushUtil.sendAppTitleMsgByList(userIds, pushDto);
 			}
 			//给角色为财务的人发送消息
 			StringBuilder openIds = new StringBuilder();

+ 127 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/util/PushUtil.java

@@ -0,0 +1,127 @@
+package org.springblade.salesPart.util;
+
+import cn.hutool.core.util.IdUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springblade.common.enums.NumberEnum;
+import org.springblade.core.tool.utils.CollectionUtil;
+import org.springblade.salesPart.enums.FinalMap;
+import org.springblade.salesPart.push.dto.AppMsgPushDto;
+import org.springblade.salesPart.push.entity.UserPushCid;
+import org.springblade.salesPart.push.mapper.UserPushCidMapper;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author Rain
+ */
+@Component
+@AllArgsConstructor
+@Slf4j
+public class PushUtil {
+
+	private final UserPushCidMapper userPushCidMapper;
+
+
+	/**
+	 * 发送单用户推送
+	 *
+	 * @param userId  用户系统id
+	 * @param pushDto 推送内容
+	 * @return 消息
+	 */
+	public String sendAppTitleMsgByOne(Long userId, AppMsgPushDto pushDto) {
+		if (Objects.isNull(userId) || Objects.isNull(pushDto)) {
+			return null;
+		}
+		UserPushCid userPush = userPushCidMapper.selectOne(new LambdaQueryWrapper<UserPushCid>().eq(UserPushCid::getUserId, userId).eq(UserPushCid::getStatus, 1).orderByDesc(UserPushCid::getLastActiveTime).last("limit 1"));
+		if (Objects.isNull(userPush)) {
+			log.error("用户id:{}没有推送id", userId);
+			return null;
+		}
+		// 必须为true,否则无法推送
+		pushDto.setDev(true);
+		if (pushDto.getContent().length() > NumberEnum.FIFTY.number) {
+			pushDto.setContent(pushDto.getContent().substring(0, 50));
+		}
+		if (pushDto.getTitle().length() > NumberEnum.TWENTY.number) {
+			pushDto.setTitle(pushDto.getTitle().substring(0, 20));
+		}
+		pushDto.setCId(userPush.getCid());
+		pushDto.setRequestId(IdUtil.getSnowflakeNextIdStr());
+		try {
+			//创建一个获取连接客户端的工具
+			CloseableHttpClient httpClient = HttpClients.createDefault();
+			//创建Post请求
+			HttpPost httpPost = new HttpPost(FinalMap.APP_PUSH_URL);
+			//添加请求头
+			httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
+			//封装请求参数,将map集合转换成json格式
+			StringEntity entity = new StringEntity(JSONObject.toJSONString(pushDto), "UTF-8");
+			//将封装的参数添加到Post请求中
+			httpPost.setEntity(entity);
+			//执行请求
+			CloseableHttpResponse response = httpClient.execute(httpPost);
+			//获取响应的实体
+			HttpEntity responseEntity = response.getEntity();
+			//转化成字符串
+			return EntityUtils.toString(responseEntity);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	public String sendAppTitleMsgByList(List<Long> userIds, AppMsgPushDto pushDto) {
+		if (CollectionUtil.isEmpty(userIds) || Objects.isNull(pushDto)) {
+			return null;
+		}
+		// 必须为true,否则无法推送
+		pushDto.setDev(true);
+		if (pushDto.getContent().length() > NumberEnum.FIFTY.number) {
+			pushDto.setContent(pushDto.getContent().substring(0, 50));
+		}
+		if (pushDto.getTitle().length() > NumberEnum.TWENTY.number) {
+			pushDto.setTitle(pushDto.getTitle().substring(0, 20));
+		}
+		List<UserPushCid> userPushCidList = userPushCidMapper.selectList(new LambdaQueryWrapper<UserPushCid>().in(UserPushCid::getUserId, userIds).eq(UserPushCid::getStatus, 1));
+		if (CollectionUtil.isEmpty(userPushCidList)) {
+			return null;
+		}
+		pushDto.setCId(userPushCidList.stream().map(UserPushCid::getCid).collect(Collectors.joining(",")));
+		pushDto.setRequestId(IdUtil.getSnowflakeNextIdStr());
+		try {
+			//创建一个获取连接客户端的工具
+			CloseableHttpClient httpClient = HttpClients.createDefault();
+			//创建Post请求
+			HttpPost httpPost = new HttpPost(FinalMap.APP_PUSH_URL);
+			//添加请求头
+			httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
+			//封装请求参数,将map集合转换成json格式
+			StringEntity entity = new StringEntity(JSONObject.toJSONString(pushDto), "UTF-8");
+			//将封装的参数添加到Post请求中
+			httpPost.setEntity(entity);
+			//执行请求
+			CloseableHttpResponse response = httpClient.execute(httpPost);
+			//获取响应的实体
+			HttpEntity responseEntity = response.getEntity();
+			//转化成字符串
+			return EntityUtils.toString(responseEntity);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+
+}

+ 1 - 1
blade-service/blade-sales-part/src/main/resources/log/logback-dev.xml

@@ -34,7 +34,7 @@
             <!-- 归档日志文件的命名模式,按天分割 -->
             <fileNamePattern>${LOG_DIR}/${springAppName:-application}.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!-- 保留日志的天数,超过此天数的旧日志文件会被自动删除 -->
-            <maxHistory>30</maxHistory>
+            <maxHistory>3</maxHistory>
             <!-- 可选:总日志文件大小限制,防止日志占满磁盘 -->
             <totalSizeCap>3GB</totalSizeCap>
         </rollingPolicy>

+ 1 - 1
blade-service/blade-sales-part/src/main/resources/log/logback-prod.xml

@@ -34,7 +34,7 @@
             <!-- 归档日志文件的命名模式,按天分割 -->
             <fileNamePattern>${LOG_DIR}/${springAppName:-application}.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!-- 保留日志的天数,超过此天数的旧日志文件会被自动删除 -->
-            <maxHistory>30</maxHistory>
+            <maxHistory>3</maxHistory>
             <!-- 可选:总日志文件大小限制,防止日志占满磁盘 -->
             <totalSizeCap>3GB</totalSizeCap>
         </rollingPolicy>

+ 1 - 1
blade-service/blade-sales-part/src/main/resources/log/logback-test.xml

@@ -34,7 +34,7 @@
             <!-- 归档日志文件的命名模式,按天分割 -->
             <fileNamePattern>${LOG_DIR}/${springAppName:-application}.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!-- 保留日志的天数,超过此天数的旧日志文件会被自动删除 -->
-            <maxHistory>30</maxHistory>
+            <maxHistory>3</maxHistory>
             <!-- 可选:总日志文件大小限制,防止日志占满磁盘 -->
             <totalSizeCap>3GB</totalSizeCap>
         </rollingPolicy>

+ 1 - 1
blade-service/blade-user/src/main/resources/log/logback-dev.xml

@@ -34,7 +34,7 @@
             <!-- 归档日志文件的命名模式,按天分割 -->
             <fileNamePattern>${LOG_DIR}/${springAppName:-application}.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!-- 保留日志的天数,超过此天数的旧日志文件会被自动删除 -->
-            <maxHistory>30</maxHistory>
+            <maxHistory>3</maxHistory>
             <!-- 可选:总日志文件大小限制,防止日志占满磁盘 -->
             <totalSizeCap>3GB</totalSizeCap>
         </rollingPolicy>

+ 1 - 1
blade-service/blade-user/src/main/resources/log/logback-prod.xml

@@ -34,7 +34,7 @@
             <!-- 归档日志文件的命名模式,按天分割 -->
             <fileNamePattern>${LOG_DIR}/${springAppName:-application}.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!-- 保留日志的天数,超过此天数的旧日志文件会被自动删除 -->
-            <maxHistory>30</maxHistory>
+            <maxHistory>3</maxHistory>
             <!-- 可选:总日志文件大小限制,防止日志占满磁盘 -->
             <totalSizeCap>3GB</totalSizeCap>
         </rollingPolicy>

+ 1 - 1
blade-service/blade-user/src/main/resources/log/logback-test.xml

@@ -34,7 +34,7 @@
             <!-- 归档日志文件的命名模式,按天分割 -->
             <fileNamePattern>${LOG_DIR}/${springAppName:-application}.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!-- 保留日志的天数,超过此天数的旧日志文件会被自动删除 -->
-            <maxHistory>30</maxHistory>
+            <maxHistory>3</maxHistory>
             <!-- 可选:总日志文件大小限制,防止日志占满磁盘 -->
             <totalSizeCap>3GB</totalSizeCap>
         </rollingPolicy>