Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/master'

ct 1 deň pred
rodič
commit
37e4a9851a

+ 16 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java

@@ -334,4 +334,20 @@ public class FsStorePaymentScrmController extends BaseController
     {
         return toAjax(fsStorePaymentService.deleteFsStorePaymentByIds(paymentIds));
     }
+
+    /**
+     * 一键发货
+     * @return R
+     * **/
+    @Log(title = "发货同步导入", businessType = BusinessType.IMPORT)
+    @PostMapping("/oneClickShipping")
+    public R oneClickShipping() {
+
+        try {
+            return fsStorePaymentService.oneClickShipping();
+        }catch (Exception e){
+            e.getStackTrace();
+        }
+        return R.ok();
+    }
 }

+ 7 - 0
fs-admin/src/main/java/com/fs/hisStore/task/LiveTask.java

@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.DateUtils;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
@@ -57,6 +58,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.LocalTime;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -230,6 +232,11 @@ public class LiveTask {
         if (list.size() > 50) {
             list = list.subList(0, 50);
         }
+        Date nowDate = DateUtils.getNowDate();
+        for (LiveOrder order : list) {
+            order.setUpdateTime(nowDate);
+        }
+        liveOrderService.batchUpdateTime(list);
         for (LiveOrder order : list) {
             ErpOrderQueryRequert request = new ErpOrderQueryRequert();
             request.setCode(order.getExtendOrderId());

+ 4 - 4
fs-service/src/main/java/com/fs/course/vo/FsCourseProductOrderVO.java

@@ -46,8 +46,8 @@ public class FsCourseProductOrderVO extends BaseEntity {
     private Long isPay;
 
     /** 支付时间 */
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date payTime;
 
     /** 支付方式 微信 */
@@ -58,8 +58,8 @@ public class FsCourseProductOrderVO extends BaseEntity {
     private Long status;
 
     /** 申请退款时间 */
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "申请退款时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "申请退款时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date refundTime;
 
     /** 申请退款理由 */

+ 12 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStorePaymentScrmMapper.java

@@ -9,6 +9,7 @@ import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.param.FsStorePaymentParam;
 import com.fs.hisStore.param.FsStoreStatisticsParam;
 import com.fs.hisStore.vo.FsStorePaymentStatisticsVO;
+import com.fs.hisStore.vo.FsStorePaymentUsetVo;
 import com.fs.hisStore.vo.FsStorePaymentVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
@@ -371,4 +372,15 @@ public interface FsStorePaymentScrmMapper
 
     @Select("select * from fs_store_payment_scrm where pay_code=#{payCode}")
     FsStorePaymentScrm selectFsStorePaymentByPaymentCode(String payCode);
+
+    /**
+     * 获取查询用户支付信息
+     * @return list
+     **/
+    List<FsStorePaymentUsetVo> getPaymentUsetInfoList();
+
+    /**
+     * 批量更新发货状态
+     * **/
+    void batchUpadte(@Param("list") List<String> list);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStorePaymentScrmService.java

@@ -116,4 +116,9 @@ public interface IFsStorePaymentScrmService
     R getWxaCodeByPayment(FsStorePaymentGetWxaCodeParam param);
 
     R paymentByWxaCode(FsStorePaymentPayParam param);
+
+    /**
+     * 批量导入更新微信订单发货状态
+     * **/
+    R oneClickShipping();
 }

+ 93 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java

@@ -3,11 +3,16 @@ package com.fs.hisStore.service.impl;
 
 import java.math.BigDecimal;
 
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.stream.Collectors;
 
 
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
@@ -41,8 +46,10 @@ import com.fs.his.service.IFsUserService;
 import com.fs.his.service.IFsUserWxService;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.utils.HttpUtil;
+import com.fs.hisStore.config.StoreConfig;
 import com.fs.hisStore.enums.SysConfigEnum;
 import com.fs.hisStore.param.*;
+import com.fs.hisStore.vo.FsStorePaymentUsetVo;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
@@ -53,6 +60,7 @@ import com.fs.hisStore.vo.FsStorePaymentStatisticsVO;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
 import com.fs.system.service.ISysConfigService;
+import com.fs.utils.TwelveDigitSnowflake;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.hisStore.domain.FsUserScrm;
 import com.fs.hisStore.service.IFsUserScrmService;
@@ -71,6 +79,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -91,6 +100,7 @@ import javax.servlet.http.HttpServletRequest;
  * @date 2022-06-20
  */
 @Service
+@Slf4j
 public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
 {
     Logger logger = LoggerFactory.getLogger(getClass());
@@ -949,4 +959,87 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
             return R.error(result.getResp_desc());
         }
     }
+
+    @Override
+    public R oneClickShipping() {
+        try {
+            StringBuilder builder = new StringBuilder();
+            //获取商城配置
+            String json = configService.selectConfigByKey("store.config");
+            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+            //验证是否开启微信发货
+            if (config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
+                //获取支付信息
+                List<FsStorePaymentUsetVo> paymentList = fsStorePaymentMapper.getPaymentUsetInfoList();
+                if (paymentList.isEmpty()) {
+                    return R.ok("操作成功,暂无同步订单信息!");
+                }
+                String uploadTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
+                        .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+                Map<String, List<FsStorePaymentUsetVo>> paymentUsetVoMap = paymentList.stream().collect(Collectors.groupingBy(FsStorePaymentUsetVo::getAppId));
+                for (Map.Entry<String, List<FsStorePaymentUsetVo>> entry : paymentUsetVoMap.entrySet()) {
+                    List<String> successList = new ArrayList<>();
+                    String appId = entry.getKey();
+                    List<FsStorePaymentUsetVo> userPayments = entry.getValue();
+                    final WxMaService wxService = WxMaConfiguration.getMaService(appId);
+                    if (!userPayments.isEmpty()) {
+                        for (FsStorePaymentUsetVo v : userPayments) {
+                            // 上传物流信息到微信
+                            if (uploadShippingInfoToWechat(wxService, v, uploadTime)) {
+                                successList.add(v.getBankTransactionId());
+                            }else {
+                                successList.add(v.getBankTransactionId());
+                            }
+                        }
+                        //批量更新数据
+                        if (!successList.isEmpty()) {
+                            fsStorePaymentMapper.batchUpadte(successList);
+                        }
+                    }
+                }
+            }
+
+
+            return R.ok(builder.toString().equals("") ? "操作成功!" : builder.toString());
+        } catch (Exception e) {
+            log.error("导入发货单快递信息失败", e);
+            return R.error("导入失败:" + e.getMessage());
+        }
+    }
+
+    private boolean uploadShippingInfoToWechat(WxMaService wxService,
+                                               FsStorePaymentUsetVo dto,
+                                               String uploadTime) {
+        try {
+            WxMaOrderShippingInfoUploadRequest request = new WxMaOrderShippingInfoUploadRequest();
+            OrderKeyBean orderKeyBean = new OrderKeyBean();
+            orderKeyBean.setOrderNumberType(2);
+            orderKeyBean.setTransactionId(dto.getBankTransactionId());//交易订单号ID
+            request.setOrderKey(orderKeyBean);
+            request.setDeliveryMode(1);
+            request.setLogisticsType(4);
+            List<ShippingListBean> shippingList = new ArrayList<>();
+            ShippingListBean shippingListBean = new ShippingListBean();
+            //默认物品信息
+            shippingListBean.setTrackingNo(String.valueOf(new TwelveDigitSnowflake(1).nextId()));
+            shippingListBean.setExpressCompany("FS");
+            shippingListBean.setItemDesc("默认商品");
+            ContactBean contactBean = new ContactBean();
+            contactBean.setReceiverContact(dto.getPhone());
+            shippingListBean.setContact(contactBean);
+
+            shippingList.add(shippingListBean);
+            request.setShippingList(shippingList);
+            request.setUploadTime(uploadTime);
+            // 设置支付者信息
+            PayerBean payerBean = new PayerBean();
+            payerBean.setOpenid(dto.getOpenId());
+            request.setPayer(payerBean);
+            // 上传物流信息
+            return wxService.getWxMaOrderShippingService().upload(request).getErrCode() == 0;
+        } catch (Exception e) {
+            log.error("上传物流信息到微信失败,订单号: {}", dto.getBankTransactionId(), e);
+            return false;
+        }
+    }
 }

+ 20 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStorePaymentUsetVo.java

@@ -0,0 +1,20 @@
+package com.fs.hisStore.vo;
+
+import lombok.Data;
+
+@Data
+public class FsStorePaymentUsetVo {
+    //交易订单号
+    private String bankTransactionId;
+
+    //openId
+    private String openId;
+
+    //手机号
+    private String phone;
+
+    /**
+     * appId
+     * **/
+    private String appId;
+}

+ 5 - 2
fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java

@@ -104,7 +104,7 @@ public interface LiveOrderMapper {
     @Select("select * from live_order where `status` = 3 AND TIMESTAMPDIFF(HOUR, start_time, NOW()) >= 48  ")
     List<LiveOrder> selectLiveOrderByFinish();
 
-    @Select("select * from live_order where `status` = 1 and extend_order_id is not null and delivery_sn is null and refund_status = 0")
+    @Select("select * from live_order where `status` = 1 and extend_order_id is not null and (delivery_sn is null or delivery_code = '') and refund_status = 0 and is_pay = 1 order by update_time ")
     List<LiveOrder> selectUpdateExpress();
 
     @Select("select order_id from live_order where `status` = 2 and delivery_code is not null and delivery_sn is not null and is_pay = 1")
@@ -454,6 +454,9 @@ public interface LiveOrderMapper {
     /*
     * 查询订单创建时间为最近30分钟的订单
     * */
-    @Select("SELECT * FROM live_order WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 MINUTE) and status = 0 and refund_status = 0")
+    @Select("SELECT * FROM live_order WHERE create_time >= DATE_SUB(NOW(), INTERVAL 15 MINUTE) and status = 0 and refund_status = 0")
     List<LiveOrder> selectBankOrder();
+
+
+    void batchUpdateTime(@Param("list") List<LiveOrder> list);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java

@@ -259,4 +259,6 @@ public interface ILiveOrderService {
     LiveOrder selectOrderByUserIdLimit1(Long userId);
 
     List<LiveOrder> selectBankOrder();
+
+    void batchUpdateTime(List<LiveOrder> list);
 }

+ 14 - 9
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -1788,15 +1788,15 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             }
             expressService.subscribeEspress(order.getOrderCode(), order.getDeliveryCode(), order.getDeliverySn(), lastFourNumber);
 
-//            TemplateBean templateBean = TemplateBean.builder()
-//                    .orderId(order.getOrderId().toString())
-//                    .orderCode(order.getOrderCode().toString())
-//                    .deliveryId(order.getDeliverySn())
-//                    .deliveryName(order.getDeliveryName())
-//                    .userId(Long.valueOf(order.getUserId()))
-//                    .templateType(TemplateListenEnum.TYPE_2.getValue())
-//                    .build();
-//            publisher.publishEvent(new TemplateEvent(this, templateBean));
+            TemplateBean templateBean = TemplateBean.builder()
+                    .orderId(order.getOrderId().toString())
+                    .orderCode(order.getOrderCode())
+                    .deliveryId(order.getDeliverySn())
+                    .deliveryName(order.getDeliveryName())
+                    .userId(Long.valueOf(order.getUserId()))
+                    .templateType(TemplateListenEnum.TYPE_2.getValue())
+                    .build();
+            publisher.publishEvent(new TemplateEvent(this, templateBean));
 
             LiveOrderPayment fsStorePayment  = liveOrderPaymentMapper.selectLiveOrderLatestPayByOrderId(order.getOrderId());
             FsWxExpressTask fsWxExpressTask = new FsWxExpressTask();
@@ -3320,6 +3320,11 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         return baseMapper.selectBankOrder();
     }
 
+    @Override
+    public void batchUpdateTime(List<LiveOrder> list) {
+        baseMapper.batchUpdateTime(list);
+    }
+
 
     @Override
     @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)

+ 0 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -442,7 +442,6 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
                                 JSON::toJSONString
                         ));
                 redisCache.hashPut(hashKey,collect);
-                log.info("同步直播在线人数到缓存完成");
             });
         }
         return liveWatchUserVOS;

+ 89 - 0
fs-service/src/main/java/com/fs/utils/TwelveDigitSnowflake.java

@@ -0,0 +1,89 @@
+package com.fs.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TwelveDigitSnowflake {
+    private final long START_TIMESTAMP = 1672502400000L;
+    private final long MACHINE_BIT = 5;
+    private final long SEQUENCE_BIT = 7;
+    private final long TIMESTAMP_BIT = 30;
+    private final long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
+    private final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
+
+    private final long MACHINE_LEFT = SEQUENCE_BIT;
+    private final long TIMESTAMP_LEFT = SEQUENCE_BIT + MACHINE_BIT;
+
+    private long machineId;
+    private long sequence = 0L;
+    private long lastTimeStamp = -1L;
+
+    // 构造函数,传入机器ID
+    public TwelveDigitSnowflake(long machineId) {
+        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
+            throw new IllegalArgumentException("机器ID超出范围");
+        }
+        this.machineId = machineId;
+    }
+
+    // 生成下一个ID
+    public synchronized long nextId() {
+        long currentTimeStamp = getCurrentTimeStamp();
+
+        // 处理时钟回拨
+        if (currentTimeStamp < lastTimeStamp) {
+            long offset = lastTimeStamp - currentTimeStamp;
+            if (offset <= 5) {
+                try {
+                    wait(offset);
+                    currentTimeStamp = getCurrentTimeStamp();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            } else { // 超过5毫秒回拨,抛出异常
+                throw new RuntimeException("时钟回拨异常,无法生成ID");
+            }
+        }
+
+        if (currentTimeStamp == lastTimeStamp) {
+            sequence = (sequence + 1) & MAX_SEQUENCE;
+            if (sequence == 0) {
+                currentTimeStamp = getNextMill();
+            }
+        } else {
+            sequence = 0L;
+        }
+
+        lastTimeStamp = currentTimeStamp;
+
+        // 组合ID:时间戳 + 机器ID + 序列号
+        long id = ((currentTimeStamp - START_TIMESTAMP) << TIMESTAMP_LEFT)
+                | (machineId << MACHINE_LEFT)
+                | sequence;
+        return id;
+    }
+
+    private long getNextMill() {
+        long mill = getCurrentTimeStamp();
+        while (mill <= lastTimeStamp) {
+            mill = getCurrentTimeStamp();
+        }
+        return mill;
+    }
+
+    private long getCurrentTimeStamp() {
+        return System.currentTimeMillis();
+    }
+
+    public static void main(String[] args) {
+        TwelveDigitSnowflake snowflake = new TwelveDigitSnowflake(1);
+        Map<String,Long> check=new HashMap<>();
+        for (int i = 0; i < 10000000; i++) {
+            long id = snowflake.nextId();
+            if(check.containsKey(String.valueOf(id))){
+                throw new RuntimeException("雪花ID重复啦!!!!!!!");
+            }
+            check.put(String.valueOf(id),0L);
+        }
+    }
+}

+ 5 - 5
fs-service/src/main/resources/application-druid-bjzm.yml

@@ -39,16 +39,16 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                  url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  url: jdbc:mysql://172.16.16.40:3306/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                   username: root
                   password: Ylrz_1q2w3e4r5t6y
                 # 从库数据源
                 slave:
                     # 从数据源开关/默认关闭
-                    enabled: false
-                    url:
-                    username:
-                    password:
+                    enabled: true
+                    url: jdbc:mysql://172.16.0.24:3306/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
                 # 初始连接数
                 initialSize: 5
                 # 最小连接池数量

+ 24 - 0
fs-service/src/main/resources/mapper/hisStore/FsStorePaymentScrmMapper.xml

@@ -200,5 +200,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </if>
     </select>
 
+    <select id="getPaymentUsetInfoList" resultType="com.fs.hisStore.vo.FsStorePaymentUsetVo">
+        SELECT
+            sp.bank_transaction_id,
+            sp.open_id,
+            sp.app_id,
+            CASE
+                WHEN TRIM(fu.phone) IS NOT NULL AND TRIM(fu.phone) != '' THEN fu.phone
+                ELSE CONCAT(
+                        ELT(FLOOR(1 + RAND() * 6), '13', '14', '15', '17', '18', '19'),
+                        LPAD(FLOOR(RAND() * 1000000000), 9, '0')
+                    )
+                END AS phone
+        FROM
+            fs_store_payment_scrm sp
+                LEFT JOIN fs_user fu ON sp.user_id = fu.user_id
+        WHERE
+            sp.status = 1 and sp.is_shipment = 0 and sp.business_type = 1 AND sp.pay_time > '2025-11-27 00:00:00' LIMIT 500
+    </select>
 
+    <update id="batchUpadte">
+        update fs_store_payment_scrm set is_shipment = 1 where bank_transaction_id in
+        <foreach item="bankTransactionId" collection="list" open="(" separator="," close=")">
+            #{bankTransactionId}
+        </foreach>
+    </update>
 </mapper>

+ 13 - 1
fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml

@@ -948,7 +948,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             o.total_num,
             o.total_price,
             o.pay_price,
-            o.pay_money,
             o.is_pay,
             o.pay_time,
             o.pay_type,
@@ -1294,4 +1293,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{item.orderNumber}
         </foreach>
     </update>
+
+    <update id="batchUpdateTime">
+        UPDATE live_order
+        SET update_time = CASE
+        <foreach collection="list" item="item" separator="">
+            WHEN order_id = #{item.orderId} THEN #{item.updateTime}
+        </foreach>
+        END
+        WHERE order_id IN
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item.orderId}
+        </foreach>
+    </update>
 </mapper>