diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java new file mode 100644 index 000000000..bd70c794c --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -0,0 +1,75 @@ +package com.czg.controller.admin; + +import com.czg.EntryManager; +import com.czg.annotation.Debounce; +import com.czg.dto.req.AggregateMerchantDto; +import com.czg.dto.resp.BankBranchDto; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import com.czg.task.EntryManagerTask; +import jakarta.annotation.Resource; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 进件管理 + * + * @author ww + */ +@AllArgsConstructor +@RestController +@RequestMapping("/admin/data/entryManager") +public class EntryManagerController { + + @Resource + private ShopDirectMerchantService shopDirectMerchantService; + @Resource + private EntryManagerTask entryManagerTask; + + /** + * 查询银行支行列表 + * + * @param province 省份 陕西省 从 /system/admin/common/region获取 + * @param city 城市 西安市 从 /system/admin/common/region获取 + * @param instId 顶级机构ID CMB 从 /system/admin/common/bankInfo 获取 + */ + @GetMapping("bankBranchList") + public CzgResult> queryBankBranchList(String province, String city, String instId) { + return CzgResult.success(EntryManager.queryBankBranchList(province, city, instId)); + } + + + /** + * 获取进件信息 + */ + @GetMapping + public CzgResult getEntry(Long shopId) { + return CzgResult.success(shopDirectMerchantService.getEntry(shopId)); + } + + /** + * 主动查询进件信息状态 + * 进件状态是INIT 待处理 AUDIT 审核中 SIGN 待签约 + * 3分钟内只能查一次 + */ + @GetMapping + @Debounce(value = "#shopId", interval = 1000 * 60 * 3) + public CzgResult queryEntry(Long shopId) { + entryManagerTask.entryManager(shopId); + return CzgResult.success(); + } + + /** + * 申请进件 + */ + @Debounce(value = "#reqDto.shopId") + @PostMapping + public CzgResult entryManager(@RequestBody AggregateMerchantDto reqDto) { + return CzgResult.success(shopDirectMerchantService.entryManager(reqDto)); + } + +} diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java new file mode 100644 index 000000000..540c3ecdd --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -0,0 +1,124 @@ +package com.czg.mq; + +import cn.hutool.core.util.StrUtil; +import com.czg.EntryManager; +import com.czg.PayCst; +import com.czg.config.RabbitConstants; +import com.czg.config.RedisCst; +import com.czg.dto.resp.EntryRespDto; +import com.czg.order.entity.ShopDirectMerchant; +import com.czg.service.RedisService; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.rabbitmq.client.Channel; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.ThreadContext; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.*; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 打印mq消息处理器 + * + * @author Administrator + */ +@Component +@Slf4j +public class EntryManagerMqListener { + @Resource + private RedisService redisService; + @Resource + private ShopDirectMerchantService shopDirectMerchantService; + + String key = RedisCst.SHOP_ENTRY; + + @RabbitListener( + bindings = @QueueBinding( + value = @Queue(value = "${spring.profiles.active}-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER, + durable = "true", exclusive = "false", autoDelete = "false"), + exchange = @Exchange(value = "${spring.profiles.active}-" + RabbitConstants.Exchange.CASH_EXCHANGE), + key = "${spring.profiles.active}-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER + ), + concurrency = "5" + ) + @RabbitHandler + public void handle(Message message, Channel channel, String msg) throws IOException { + String messageId = message.getMessageProperties().getMessageId(); + if (hasMessageId(messageId)) { + return; + } + try { + Long shopId = Long.valueOf(msg); + // 将唯一标识添加到日志上下文 + ThreadContext.put("traceId", messageId); + // 安全转换shopId + if (shopId == null) { + channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); + return; + } + AggregateMerchantVO entry = shopDirectMerchantService.getEntry(Long.valueOf(msg)); + if (entry != null) { + EntryManager.uploadParamImage(entry); + List platform = new ArrayList<>(); + if (PayCst.EntryStatus.WAIT.equals(entry.getAlipayStatus())) { + platform.add(PayCst.Platform.ALIPAY); + } + if (PayCst.EntryStatus.WAIT.equals(entry.getWechatStatus())) { + platform.add(PayCst.Platform.WECHAT); + } + EntryRespDto resp = EntryManager.entryMerchant(entry, platform.toArray(new String[0])); + ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setShopId(entry.getShopId()); + + merchant.setWechatStatus(resp.getWechatStatus()); + merchant.setWechatErrorMsg(resp.getWechatErrorMsg()); + + merchant.setAlipayStatus(resp.getAlipayStatus()); + merchant.setAlipayErrorMsg(resp.getAlipayErrorMsg()); + shopDirectMerchantService.updateById(merchant); + } + channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); + } catch (Exception e) { + log.error("进件MQ对接业务异常shopId:{}", msg, e); + ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setShopId(Long.valueOf(msg)); + merchant.setWechatStatus(PayCst.EntryStatus.REJECTED); + merchant.setAlipayStatus(PayCst.EntryStatus.REJECTED); + merchant.setErrorMsg("系统错误,请联系管理员后重试。"); + shopDirectMerchantService.updateById(merchant); + + channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); + } finally { + delMessageId(messageId); + // 清除日志上下文信息 + ThreadContext.remove("messageId"); + } + } + + public boolean hasMessageId(String messageId) { + if (!redisService.hasKey(key)) { + if (StrUtil.isNotBlank(messageId)) { + redisService.leftPush(key, messageId); + return false; + } else { + return true; + } + } + List list = redisService.lGet(key, 0, -1); + if (!list.contains(messageId)) { + redisService.leftPush(key, messageId); + return false; + } + return true; + } + + public void delMessageId(String messageId) { + redisService.lRemove(key, 0, messageId); + } + +} diff --git a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java index 0657298ac..c098099e7 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java @@ -29,18 +29,14 @@ public class PrintMqListener { private MqLogService mqLogService; @Resource private FunUtil funUtil; - - // 注入自定义线程池(建议单独配置,避免使用默认线程池) - @Resource - private ThreadPoolTaskExecutor asyncExecutor; @Lazy @Resource private PrinterHandler printerHandler; - private void invokeFun(String type, String plat, T data, Consumer consumer) { + private void invokeFun(String queue, String type, String plat, T data, Consumer consumer) { long startTime = DateUtil.date().getTime(); log.info("接收到{}打印消息:{}", type, data); - MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE).setMsg(data.toString()) + MqLog mqLog = new MqLog().setQueue(queue).setMsg(data.toString()) .setType(type).setPlat(plat).setCreateTime(DateUtil.date().toLocalDateTime()); try { consumer.accept(data); @@ -56,7 +52,7 @@ public class PrintMqListener { @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE}) public void orderPrint(String req) { // 执行核心打印逻辑 - invokeFun("orderPrint", "java.order", req, (data) -> { + invokeFun(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, "orderPrint", "java.order", req, (data) -> { JSONObject jsonObject = JSONObject.parseObject(data); String orderId = jsonObject.getString("orderId"); if (orderId == null) { @@ -68,33 +64,6 @@ public class PrintMqListener { return null; }, RedisCst.getLockKey("orderPrint", orderId)); }); -// // 使用异步线程池执行延迟任务,不阻塞当前消费者线程 -// CompletableFuture.runAsync(() -> { -// try { -// // 延迟3秒处理 -// TimeUnit.SECONDS.sleep(3); -// // 执行核心打印逻辑 -// invokeFun("orderPrint", "java.order", req, (data) -> { -// JSONObject jsonObject = JSONObject.parseObject(data); -// String orderId = jsonObject.getString("orderId"); -// if (orderId == null) { -// throw new RuntimeException("订单打印失败,未传递orderId"); -// } -// Boolean printOrder = jsonObject.getBoolean("printOrder"); -// funUtil.runFunAndCheckKey(() -> { -// printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); -// return null; -// }, RedisCst.getLockKey("orderPrint", orderId)); -// }); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// // 记录中断日志 -// log.warn("打印任务被中断,req:{}", req, e); -// } catch (Exception e) { -// // 记录业务异常日志 -// log.error("打印任务处理失败,req:{}", req, e); -// } -// }, asyncExecutor); } /** @@ -102,14 +71,16 @@ public class PrintMqListener { */ @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE}) public void handoverPrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER)); + invokeFun(RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, "handoverPrint", "java.order", id, (data) -> + printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER)); } /** - * 交班打印 + * 叫号打印 */ - @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE}) + @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_QUEUE}) public void callTablePrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL)); + invokeFun(RabbitConstants.Queue.CALL_TABLE_QUEUE, "callTable", "java.order", id, (data) -> + printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL)); } } diff --git a/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java new file mode 100644 index 000000000..e8662c092 --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java @@ -0,0 +1,87 @@ +package com.czg.task; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.czg.EntryManager; +import com.czg.PayCst; +import com.czg.account.entity.ShopInfo; +import com.czg.account.service.ShopInfoService; +import com.czg.dto.resp.QueryStatusResp; +import com.czg.order.entity.ShopDirectMerchant; +import com.czg.order.service.ShopOrderStatisticService; +import com.czg.order.service.ShopProdStatisticService; +import com.czg.order.service.ShopTableOrderStatisticService; +import com.czg.service.RedisService; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 进件查询 + * + * @author ww + */ +@Component +@Slf4j +public class EntryManagerTask { + @Resource + private ShopDirectMerchantService shopDirectMerchantService; + @DubboReference + private ShopInfoService shopInfoService; + + //每10分钟查一次 + @Scheduled(cron = "0 0/10 * * * ? ") + public void run() { + log.info("进件查询,定时任务执行"); + long start = System.currentTimeMillis(); + entryManager(null); + log.info("进件查询,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis()); + } + + /** + * 查询状态为待处理、待签约、待审核的进件 + */ + public void entryManager(Long shopId) { + List list = shopDirectMerchantService.list(QueryWrapper.create() + .eq(ShopDirectMerchant::getShopId, shopId) + .in(ShopDirectMerchant::getWechatStatus, PayCst.EntryStatus.NEED_QUERY_LIST) + .or(ShopDirectMerchant::getAlipayStatus).in(PayCst.EntryStatus.NEED_QUERY_LIST)); + if (CollUtil.isEmpty(list)) { + return; + } + for (ShopDirectMerchant shopDirectMerchant : list) { + String wechatMerchantId = ""; + String alipayMerchantId = ""; + if (PayCst.EntryStatus.NEED_QUERY_LIST.contains(shopDirectMerchant.getWechatStatus())) { + QueryStatusResp wechatStatus = EntryManager.queryWechatEntryStatus(shopDirectMerchant.getMerchantCode()); + shopDirectMerchant.setWechatStatus(wechatStatus.getStatus()); + shopDirectMerchant.setWechatErrorMsg(wechatStatus.getFailReason()); + shopDirectMerchant.setWechatSignUrl(wechatStatus.getSignUrl()); + if (PayCst.EntryStatus.FINISH.equals(wechatStatus.getStatus())) { + wechatMerchantId = wechatStatus.getThirdMerchantId(); + } + } + if (PayCst.EntryStatus.NEED_QUERY_LIST.contains(shopDirectMerchant.getAlipayStatus())) { + QueryStatusResp alipayStatus = EntryManager.queryAlipayEntryStatus(shopDirectMerchant.getMerchantCode()); + shopDirectMerchant.setAlipayStatus(alipayStatus.getStatus()); + shopDirectMerchant.setAlipayErrorMsg(alipayStatus.getFailReason()); + shopDirectMerchant.setAlipaySignUrl(alipayStatus.getSignUrl()); + if (PayCst.EntryStatus.FINISH.equals(alipayStatus.getStatus())) { + alipayMerchantId = alipayStatus.getThirdMerchantId(); + } + } + shopDirectMerchantService.updateById(shopDirectMerchant); + if (StrUtil.isNotBlank(wechatMerchantId) || StrUtil.isNotBlank(alipayMerchantId)) { + shopInfoService.editEntry(shopDirectMerchant.getShopId(), wechatMerchantId, alipayMerchantId); + } + } + } +} \ No newline at end of file diff --git a/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java b/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java index b94bc7c66..7a6f4fdfa 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java @@ -28,6 +28,7 @@ import java.util.List; /** * 订单过期处理 + * 退款失败 补偿 * * @author ww */ diff --git a/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java b/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java new file mode 100644 index 000000000..2585c6995 --- /dev/null +++ b/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java @@ -0,0 +1,61 @@ +package com.czg.controller.admin; + +import com.czg.BaseQueryParam; +import com.czg.resp.CzgResult; +import com.czg.system.entity.SysBankInfo; +import com.czg.system.entity.SysCategoryInfo; +import com.czg.system.entity.SysRegion; +import com.czg.system.service.SysBankInfoService; +import com.czg.system.service.SysCategoryInfoService; +import com.czg.system.service.SysRegionService; +import com.czg.system.vo.SysCategoryInfoVO; +import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * 通用 + * + * @author Administrator + */ +@RestController +@RequestMapping("/admin/common") +public class SysCommonController { + @Resource + private SysRegionService sysRegionService; + @Resource + private SysBankInfoService bankInfoService; + @Resource + private SysCategoryInfoService categoryInfoService; + + /** + * 获取所有地域 + */ + @GetMapping("/region") + public CzgResult> region() { + return CzgResult.success(sysRegionService.regionList()); + } + + /** + * 获取银行信息 + */ + @GetMapping("/bankInfo") + public CzgResult> bankInfo(BaseQueryParam param, @RequestParam String bankName) { + return CzgResult.success(bankInfoService.bankInfoList(param, bankName)); + } + + + /** + * 类目信息表 + */ + @GetMapping("/category") + public CzgResult> category() { + return CzgResult.success(categoryInfoService.categoryList()); + } +} diff --git a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java index 5ba087dca..ab5b007cc 100644 --- a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java +++ b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java @@ -21,12 +21,24 @@ public class RabbitConfig { @Value("${spring.profiles.active}") private String activeProfile; + @Bean @Primary public DirectExchange directExchange() { return new DirectExchange(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE); } + //------------------------------------------------------ 商家入驻 + @Bean + public Queue entryManagerQueue() { + return new Queue(activeProfile + "-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER, true, false, false); + } + + @Bean + public Binding entryManagerExchange(Queue entryManagerQueue, DirectExchange exchange) { + return BindingBuilder.bind(entryManagerQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER); + } + //------------------------------------------------------订单打印队列 @Bean public Queue orderPrintQueue() { @@ -36,6 +48,7 @@ public class RabbitConfig { args.put("x-message-ttl", 180000); return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE, true, false, false, args); } + @Bean public Binding bindingOrderPrintExchange(Queue orderPrintQueue, DirectExchange exchange) { return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE); @@ -51,6 +64,7 @@ public class RabbitConfig { // args.put("x-message-ttl", 180000); return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, true, false, false); } + @Bean public Binding bindingOrderMachinePrintExchange(Queue orderMachinePrintQueue, DirectExchange exchange) { return BindingBuilder.bind(orderMachinePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE); @@ -61,6 +75,7 @@ public class RabbitConfig { public Queue handoverPrintQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, true, false, false); } + @Bean public Binding bindingHandoverPrintExchange(Queue handoverPrintQueue, DirectExchange exchange) { return BindingBuilder.bind(handoverPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE); @@ -69,11 +84,12 @@ public class RabbitConfig { //------------------------------------------------------叫号 打票 @Bean public Queue callTablePrintQueue() { - return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE, true, false, false); + return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE, true, false, false); } + @Bean public Binding bindingCallTablePrintExchange(Queue callTablePrintQueue, DirectExchange exchange) { - return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE); + return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE); } //------------------------------------------------------订单取消 @@ -81,9 +97,10 @@ public class RabbitConfig { public Queue orderCancelQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE, true); } + @Bean - public Binding bindingOrderCancelExchange(Queue orderPrintQueue, DirectExchange exchange) { - return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE); + public Binding bindingOrderCancelExchange(Queue orderCancelQueue, DirectExchange exchange) { + return BindingBuilder.bind(orderCancelQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE); } //------------------------------------------------------ 订单库存更新 @@ -91,6 +108,7 @@ public class RabbitConfig { public Queue orderStockQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE, true); } + @Bean public Binding bindingOrderStockExchange(Queue orderStockQueue, DirectExchange exchange) { return BindingBuilder.bind(orderStockQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE); @@ -102,6 +120,7 @@ public class RabbitConfig { public Queue productInfoChangeQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE, true); } + @Bean public Binding bindingProductInfoChange(Queue productInfoChangeQueue, DirectExchange exchange) { return BindingBuilder.bind(productInfoChangeQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE); @@ -112,6 +131,7 @@ public class RabbitConfig { public Queue orderRefundQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE, true); } + @Bean public Binding bindingOrderRefundExchange(Queue orderRefundQueue, DirectExchange exchange) { return BindingBuilder.bind(orderRefundQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE); @@ -119,6 +139,7 @@ public class RabbitConfig { //------------------------------------------------------ 申请短信模板队列 + /** * 1,2,applySmsTemp 模版审核 * 1,2,sendMarkSms 发送营销短信 @@ -129,16 +150,18 @@ public class RabbitConfig { public Queue applySmsTemplateQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE, true); } + @Bean public Binding bindingApplySmsTemplateExchange(Queue applySmsTemplateQueue, DirectExchange exchange) { return BindingBuilder.bind(applySmsTemplateQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE); } - //------------------------------------------------------ 生日礼品短信队列 + //------------------------------------------------------ 生日礼品短信队列 @Bean public Queue birthdayGiftSmsQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE, true); } + @Bean public Binding bindingBirthdayGiftSmsExchange(Queue birthdayGiftSmsQueue, DirectExchange exchange) { return BindingBuilder.bind(birthdayGiftSmsQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE); @@ -149,6 +172,7 @@ public class RabbitConfig { public Queue orderProductStatusQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, true); } + @Bean public Binding bindingOrderProductStatusExchange(Queue orderProductStatusQueue, DirectExchange exchange) { return BindingBuilder.bind(orderProductStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE); @@ -160,6 +184,7 @@ public class RabbitConfig { public Queue orderDetailStatusQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE, true); } + @Bean public Binding bindingOrderDetailStatusExchange(Queue orderDetailStatusQueue, DirectExchange exchange) { return BindingBuilder.bind(orderDetailStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE); diff --git a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java index c43827b41..d4a0a9b69 100644 --- a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java +++ b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java @@ -10,13 +10,14 @@ public interface RabbitConstants { } class Queue { + public static final String SHOP_ENTRY_MANAGER = "shop.entry.manager"; public static final String ORDER_STOCK_QUEUE = "order.stock.queue"; public static final String ORDER_REFUND_QUEUE = "order.refund.queue"; public static final String ORDER_CANCEL_QUEUE = "order.cancel.queue"; public static final String ORDER_PRINT_QUEUE = "order.print.queue"; public static final String ORDER_MACHINE_PRINT_QUEUE = "order.machine.print.queue"; public static final String ORDER_HANDOVER_PRINT_QUEUE = "order.handover.print.queue"; - public static final String CALL_TABLE_PRINT_QUEUE = "call.table.print.queue"; + public static final String CALL_TABLE_QUEUE = "call.table.print.queue"; public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue"; /** diff --git a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java index a5e49a8a5..8903cad34 100644 --- a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java +++ b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java @@ -130,6 +130,13 @@ public class RabbitPublisher { sendMsg(RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, qrContent); } + /** + * 订单商品状态消息 + */ + public void sendEntryManagerMsg(String shopId) { + sendMsg(RabbitConstants.Queue.SHOP_ENTRY_MANAGER, shopId); + } + /** * 订单商品状态消息 diff --git a/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java b/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java index cbfd9dd99..e915eb0f0 100644 --- a/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java +++ b/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java @@ -33,6 +33,8 @@ public interface RedisCst { public static final String EXPIRED_WECHAT = "expired:wechat:"; } + //商家进件 + String SHOP_ENTRY = "shop:entry"; String SMS_CODE = "sms:code:"; // 店铺会员动态支付码 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java index 359870ae8..2e6667eca 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java @@ -142,6 +142,14 @@ public class ShopInfo implements Serializable { * -1 平台禁用 0-过期,1正式营业, */ private Integer status; + /** + * 微信商户id + */ + private String wechatMerchantId; + /** + * 支付宝商户id + */ + private String alipayMerchantId; /** * 到期时间 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java index f87dfec90..dcb5e7af2 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java @@ -37,6 +37,11 @@ public interface ShopInfoService extends IService { Boolean edit(ShopInfoEditDTO shopInfoEditDTO); + /** + * 进件结果保存 + */ + Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId); + ShopDetailDTO detail(Long id) throws CzgException; ShopInfoByCodeDTO getByCode(String tableCode, String lat, String lng, boolean checkState); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java new file mode 100644 index 000000000..5fbea4472 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java @@ -0,0 +1,111 @@ +package com.czg.order.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 商户进件 实体类。 + * + * @author ww + * @since 2026-01-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("tb_shop_direct_merchant") +public class ShopDirectMerchant implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺id + */ + @Id + private Long shopId; + + /** + * 营业执照编号 + */ + private String licenceNo; + + /** + * 商户编号(在当前系统唯一) + */ + private String merchantCode; + + /** + * 商户基础信息 + */ + private String merchantBaseInfo; + + /** + * 法人信息 + */ + private String legalPersonInfo; + + /** + * 营业执照信息 + */ + private String businessLicenceInfo; + + /** + * 门店信息 + */ + private String storeInfo; + + /** + * 结算信息 + */ + private String settlementInfo; + + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + + + private String errorMsg; + + /** + * 微信状态 + */ + private String wechatStatus; + + /** + * 微信进件错误信息 + */ + private String wechatErrorMsg; + /** + * 微信进件签名地址 + */ + private String wechatSignUrl; + + /** + * 支付宝状态 + */ + private String alipayStatus; + + /** + * 支付宝进件错误信息 + */ + private String alipayErrorMsg; + /** + * 支付宝进件签名地址 + */ + private String alipaySignUrl; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java new file mode 100644 index 000000000..bc298d759 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java @@ -0,0 +1,82 @@ +package com.czg.system.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 银行账户信息表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sys_bank_info") +public class SysBankInfo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @Id(keyType = KeyType.Auto) + private BigInteger id; + + /** + * 银行名称 + */ + private String accountBank; + + /** + * 银行数字编码 + */ + private Integer accountBankCode; + + /** + * 银行别名 + */ + private String bankAlias; + + /** + * 银行别名编码 + */ + private String bankAliasCode; + + /** + * 不知道干啥的 + */ + private Boolean needBankBranch; + + /** + * 银行英文编码 + */ + private String bankCode; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java new file mode 100644 index 000000000..1fe2a78c7 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java @@ -0,0 +1,77 @@ +package com.czg.system.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 类目信息表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sys_category_info") +public class SysCategoryInfo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @Id(keyType = KeyType.Auto) + private BigInteger id; + + /** + * 一级类目 + */ + private String firstCategory; + + /** + * 二级类目code + */ + private String secondCategoryCode; + + /** + * 二级类目 + */ + private String secondCategory; + + /** + * 适用商家说明 + */ + private String applicableMerchant; + + /** + * 特殊资质(为空则无需提供) + */ + private String specialQualification; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java new file mode 100644 index 000000000..1b50b9e9a --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java @@ -0,0 +1,70 @@ +package com.czg.system.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; + +import java.io.Serial; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 行政区表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sys_region") +public class SysRegion implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 区域编码 + */ + @Id + private String regionId; + + /** + * 上级区域编码 + */ + private String parentRegionId; + + /** + * 区域级别:1=国家,2=省,3=市,4=县 + */ + @Id + private Integer regionLevel; + + /** + * 区域中文全称 + */ + private String regionName; + + /** + * 区域拼音 + */ + private String regionPinyin; + + /** + * 全级别名称(如“中国|北京|北京市|东城区) + */ + private String fullName; + + /** + * 子级区域 + */ + @Column(ignore = true) + private List children; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java new file mode 100644 index 000000000..d4510f052 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java @@ -0,0 +1,19 @@ +package com.czg.system.service; + +import com.czg.BaseQueryParam; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; +import com.czg.system.entity.SysBankInfo; + +import java.util.List; + +/** + * 银行账户信息表 服务层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysBankInfoService extends IService { + + Page bankInfoList(BaseQueryParam param, String bankName); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java new file mode 100644 index 000000000..78eaee526 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java @@ -0,0 +1,20 @@ +package com.czg.system.service; + +import com.czg.system.vo.SysCategoryInfoVO; +import com.mybatisflex.core.service.IService; +import com.czg.system.entity.SysCategoryInfo; + +import java.util.List; +import java.util.Map; + +/** + * 类目信息表 服务层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysCategoryInfoService extends IService { + + + List categoryList(); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java new file mode 100644 index 000000000..d1f2646ec --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java @@ -0,0 +1,17 @@ +package com.czg.system.service; + +import com.mybatisflex.core.service.IService; +import com.czg.system.entity.SysRegion; + +import java.util.List; + +/** + * 行政区表 服务层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysRegionService extends IService { + + List regionList(); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java b/cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java new file mode 100644 index 000000000..a3d535d7a --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java @@ -0,0 +1,40 @@ +package com.czg.system.vo; + +import com.czg.system.entity.SysCategoryInfo; +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 类目信息表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysCategoryInfoVO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 一级类目 + */ + private String firstCategory; + + private List child; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java index 52de66b27..8bce68aae 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java @@ -1,7 +1,10 @@ package com.czg; +import java.util.List; + /** * 支付相关常量 + * * @author yjjie * @date 2026/1/7 09:20 */ @@ -34,7 +37,6 @@ public interface PayCst { * 待处理 */ public static final String INIT = "INIT"; - /** * 审核中 */ @@ -54,6 +56,13 @@ public interface PayCst { * 失败 */ public static final String REJECTED = "REJECTED"; + + + /** + * 需要查询的状态列表 + * 待处理、待签约、待审核的进件 + */ + public static final List NEED_QUERY_LIST = List.of(INIT, AUDIT, SIGN); } /** diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java index bdc521828..e72937618 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java @@ -10,9 +10,14 @@ import lombok.Data; */ @Data public class AggregateMerchantDto { + /** + * 商户Id + */ + private Long shopId; /** * 【必填】 + * 自己生成 CZGyyyy-MM-dd HH:mm:ss.SSS * 商户编号(在当前系统唯一) */ private String merchantCode; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java index ae8384f60..3bebf4567 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java @@ -16,7 +16,7 @@ public class MerchantBaseInfoDto { * 商户类型 * 0: 个体商户; * 1: 企业商户; - * 3: 小微商户 + * 3: 小微商户 暂不支持 */ private String userType; diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java index f273175cc..388b789e0 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java @@ -324,6 +324,15 @@ public class ShopInfoServiceImpl extends ServiceImpl i return false; } + @Override + @CacheEvict(key = "#shopId") + public Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId) { + ShopInfo shopInfo = new ShopInfo(); + shopInfo.setWechatMerchantId(wechatMerchantId); + shopInfo.setAlipayMerchantId(alipayMerchantId); + return update(shopInfo, new QueryWrapper().eq(ShopInfo::getId, shopId)); + } + @Override public ShopDetailDTO detail(Long id) throws CzgException { ShopInfo shopInfo = queryChain().eq(ShopInfo::getId, id == null ? StpKit.USER.getShopId() : id).one(); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java b/cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java new file mode 100644 index 000000000..28498f898 --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java @@ -0,0 +1,52 @@ +package com.czg.service.order.dto; + +import com.czg.dto.req.*; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author ww + */ +@Data +public class AggregateMerchantVO extends AggregateMerchantDto{ + + private LocalDateTime createTime; + + private LocalDateTime updateTime; + + private String errorMsg; + + /** + * {@link com.czg.PayCst.EntryStatus} + * 微信状态 + * WAIT 待提交 INIT 待处理 AUDIT 审核中 SIGN 待签约 REJECTED 失败 FINISH 已完成 + */ + private String wechatStatus; + + /** + * 微信进件错误信息 + */ + private String wechatErrorMsg; + /** + * 微信进件签名地址 + */ + private String wechatSignUrl; + + /** + * {@link com.czg.PayCst.EntryStatus} + * 支付宝状态 + * WAIT 待提交 INIT 待处理 AUDIT 审核中 SIGN 待签约 REJECTED 失败 FINISH 已完成 + */ + private String alipayStatus; + + /** + * 支付宝进件错误信息 + */ + private String alipayErrorMsg; + /** + * 支付宝进件签名地址 + */ + private String alipaySignUrl; + +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java new file mode 100644 index 000000000..3b97bdb5a --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.order.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.order.entity.ShopDirectMerchant; + +/** + * 商户进件 映射层。 + * + * @author ww + * @since 2026-01-07 + */ +public interface ShopDirectMerchantMapper extends BaseMapper { + +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java new file mode 100644 index 000000000..6519ae2af --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java @@ -0,0 +1,19 @@ +package com.czg.service.order.service; +import com.czg.dto.req.AggregateMerchantDto; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.mybatisflex.core.service.IService; +import com.czg.order.entity.ShopDirectMerchant; + +/** + * 商户进件 服务层。 + * + * @author ww + * @since 2026-01-07 + */ +public interface ShopDirectMerchantService extends IService { + + + AggregateMerchantVO getEntry(Long shopId); + + boolean entryManager(AggregateMerchantDto reqDto); +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java new file mode 100644 index 000000000..cf146543f --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java @@ -0,0 +1,133 @@ +package com.czg.service.order.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.io.unit.DataSizeUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.czg.EntryManager; +import com.czg.PayCst; +import com.czg.config.RabbitPublisher; +import com.czg.dto.req.*; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.czg.utils.FunUtils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.order.entity.ShopDirectMerchant; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.czg.service.order.mapper.ShopDirectMerchantMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; + +/** + * 商户进件 服务层实现。 + * + * @author ww + * @since 2026-01-07 + */ +@Service +public class ShopDirectMerchantServiceImpl extends ServiceImpl implements ShopDirectMerchantService { + + @Resource + private RabbitPublisher rabbitPublisher; + // 全局原子计数器,按天重置(避免数值过大) + private static final AtomicLong COUNTER = new AtomicLong(0); + // 记录上一次的日期,用于重置计数器 + private static String LAST_DATE = DateUtil.format(new Date(), "yyyyMMdd"); + + @Override + public AggregateMerchantVO getEntry(Long shopId) { + ShopDirectMerchant merchant = getById(shopId); + if (merchant == null) { + return null; + } + return convertVO(merchant); + } + + @Override + public boolean entryManager(AggregateMerchantDto reqDto) { + boolean isSave = false; + boolean result; + if (StrUtil.isBlank(reqDto.getMerchantCode())) { + reqDto.setMerchantCode(getMerchantCode()); + isSave = true; + } + EntryManager.verifyEntryParam(reqDto); + + + ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setShopId(reqDto.getShopId()); + merchant.setMerchantCode(reqDto.getMerchantCode()); + merchant.setLicenceNo(reqDto.getBusinessLicenceInfo().getLicenceNo()); + + merchant.setMerchantBaseInfo(JSONObject.toJSONString(reqDto.getMerchantBaseInfo())); + merchant.setLegalPersonInfo(JSONObject.toJSONString(reqDto.getLegalPersonInfo())); + merchant.setBusinessLicenceInfo(JSONObject.toJSONString(reqDto.getBusinessLicenceInfo())); + merchant.setStoreInfo(JSONObject.toJSONString(reqDto.getStoreInfo())); + merchant.setSettlementInfo(JSONObject.toJSONString(reqDto.getSettlementInfo())); + merchant.setWechatStatus(PayCst.EntryStatus.WAIT); + merchant.setAlipayStatus(PayCst.EntryStatus.WAIT); + if (isSave) { + result = save(merchant); + } else { + result = updateById(merchant); + } + //发送进件队列消息 + FunUtils.transactionSafeRun(() -> rabbitPublisher.sendEntryManagerMsg(reqDto.getShopId().toString())); + return result; + } + + private static String getMerchantCode() { + Date now = new Date(); + // 1. 获取当前日期(yyyyMMdd) + String currentDate = DateUtil.format(now, "yyyyMMdd"); + // 2. 每天重置计数器,避免数值溢出 + synchronized (COUNTER) { + if (!currentDate.equals(LAST_DATE)) { + COUNTER.set(0); + LAST_DATE = currentDate; + } + } + // 3. 原子递增,获取唯一序号(同一毫秒内不会重复) + long seq = COUNTER.incrementAndGet(); + // 4. 时间戳(毫秒级)+ 6位序号(补零) + String timeStr = DateUtil.format(now, "yyyyMMddHHmmss"); + String seqStr = String.format("%03d", seq); + return "CZG" + timeStr + seqStr; + } + + + public AggregateMerchantVO convertVO(ShopDirectMerchant entity) { + if (entity == null) { + return null; + } + + AggregateMerchantVO vo = new AggregateMerchantVO(); + vo.setShopId(entity.getShopId()); + vo.setMerchantCode(entity.getMerchantCode()); + + // 解析JSON字段 + vo.setMerchantBaseInfo(JSONObject.parseObject(entity.getMerchantBaseInfo(), MerchantBaseInfoDto.class)); + vo.setLegalPersonInfo(JSONObject.parseObject(entity.getLegalPersonInfo(), LegalPersonInfoDto.class)); + vo.setBusinessLicenceInfo(JSONObject.parseObject(entity.getBusinessLicenceInfo(), BusinessLicenceInfoDto.class)); + vo.setStoreInfo(JSONObject.parseObject(entity.getStoreInfo(), StoreInfoDto.class)); + vo.setSettlementInfo(JSONObject.parseObject(entity.getSettlementInfo(), SettlementInfoDto.class)); + + // 设置其他字段 + vo.setCreateTime(entity.getCreateTime()); + vo.setUpdateTime(entity.getUpdateTime()); + vo.setWechatStatus(entity.getWechatStatus()); + vo.setWechatErrorMsg(entity.getWechatErrorMsg()); + vo.setWechatSignUrl(entity.getWechatSignUrl()); + vo.setAlipayStatus(entity.getAlipayStatus()); + vo.setAlipayErrorMsg(entity.getAlipayErrorMsg()); + vo.setAlipaySignUrl(entity.getAlipaySignUrl()); + + return vo; + } +} diff --git a/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml new file mode 100644 index 000000000..ba52848f4 --- /dev/null +++ b/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/pay-service/pom.xml b/cash-service/pay-service/pom.xml index 92db97998..522c91c55 100644 --- a/cash-service/pay-service/pom.xml +++ b/cash-service/pay-service/pom.xml @@ -26,6 +26,11 @@ czg-pay ${project.version} + + com.czg + aggregation-pay + ${project.version} + diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java new file mode 100644 index 000000000..92c6db03a --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.system.entity.SysBankInfo; + +/** + * 银行账户信息表 映射层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysBankInfoMapper extends BaseMapper { + +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java new file mode 100644 index 000000000..84d0d82a8 --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.system.entity.SysCategoryInfo; + +/** + * 类目信息表 映射层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysCategoryInfoMapper extends BaseMapper { + +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java new file mode 100644 index 000000000..b438c3d3d --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.system.entity.SysRegion; + +/** + * 行政区表 映射层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysRegionMapper extends BaseMapper { + +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java new file mode 100644 index 000000000..9678422fb --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java @@ -0,0 +1,26 @@ +package com.czg.service.system.service.impl; + +import com.czg.BaseQueryParam; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.system.entity.SysBankInfo; +import com.czg.system.service.SysBankInfoService; +import com.czg.service.system.mapper.SysBankInfoMapper; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 银行账户信息表 服务层实现。 + * + * @author ww + * @since 2026-01-06 + */ +@Service +public class SysBankInfoServiceImpl extends ServiceImpl implements SysBankInfoService { + + @Override + public Page bankInfoList(BaseQueryParam param, String bankName) { + return page(Page.of(param.getPage(), param.getSize()), query().like(SysBankInfo::getBankAlias, bankName)); + } +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java new file mode 100644 index 000000000..f8ea19e9e --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java @@ -0,0 +1,43 @@ +package com.czg.service.system.service.impl; + +import cn.hutool.core.collection.CollStreamUtil; +import cn.hutool.core.collection.CollUtil; +import com.czg.system.vo.SysCategoryInfoVO; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.system.entity.SysCategoryInfo; +import com.czg.system.service.SysCategoryInfoService; +import com.czg.service.system.mapper.SysCategoryInfoMapper; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 类目信息表 服务层实现。 + * + * @author ww + * @since 2026-01-06 + */ +@Service +public class SysCategoryInfoServiceImpl extends ServiceImpl implements SysCategoryInfoService { + + @Cacheable(value = "common:category", key = "'all'") + @Override + public List categoryList() { + List list = list(); + if (CollUtil.isEmpty(list)) { + return List.of(); + } + List result = new ArrayList<>(); + Map> stringListMap = CollStreamUtil.groupByKey(list, SysCategoryInfo::getFirstCategory); + stringListMap.forEach((k, v) -> { + SysCategoryInfoVO vo = new SysCategoryInfoVO(); + vo.setFirstCategory(k); + vo.setChild(v); + result.add(vo); + }); + return result; + } +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java new file mode 100644 index 000000000..4820a7190 --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java @@ -0,0 +1,56 @@ +package com.czg.service.system.service.impl; + +import com.czg.service.system.mapper.SysRegionMapper; +import com.czg.system.entity.SysRegion; +import com.czg.system.service.SysRegionService; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 行政区表 服务层实现。 + * + * @author ww + * @since 2026-01-06 + */ +@Service +public class SysRegionServiceImpl extends ServiceImpl implements SysRegionService { + + + @Cacheable(value = "common:region", key = "'all'") + @Override + public List regionList() { + // 1. 单次查询获取所有数据 + List allRegions = list(query().ne(SysRegion::getRegionLevel, 1)); + // 2. 一次性按层级分组,减少流遍历次数 + Map> regionByLevel = allRegions.stream() + .collect(Collectors.groupingBy(SysRegion::getRegionLevel)); + + // 3. 获取各层级数据,默认空列表避免空指针 + List parents = regionByLevel.getOrDefault(2, List.of()); + List level3Regions = regionByLevel.getOrDefault(3, List.of()); + List level4Regions = regionByLevel.getOrDefault(4, List.of()); + + // 4. 构建3级地区的子节点映射(4级),使用HashMap保证性能 + Map> level4ByParentId = level4Regions.stream() + .collect(Collectors.groupingBy(SysRegion::getParentRegionId, Collectors.toList())); + + level3Regions.forEach(level3 -> { + List children = level4ByParentId.getOrDefault(level3.getRegionId(), List.of()); + level3.setChildren(children); + }); + + Map> level3ByParentId = level3Regions.stream() + .collect(Collectors.groupingBy(SysRegion::getParentRegionId)); + + parents.forEach(parent -> { + List children = level3ByParentId.getOrDefault(parent.getRegionId(), List.of()); + parent.setChildren(children); + }); + return parents; + } +} diff --git a/cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml b/cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml new file mode 100644 index 000000000..0edfabab3 --- /dev/null +++ b/cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml b/cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml new file mode 100644 index 000000000..b3a1df485 --- /dev/null +++ b/cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml b/cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml new file mode 100644 index 000000000..bb643d005 --- /dev/null +++ b/cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml @@ -0,0 +1,7 @@ + + + + +