From a2e0854a7df4cde1cb9c3cc5cd5e315f8b881fdc Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Tue, 18 Nov 2025 16:52:45 +0800 Subject: [PATCH 01/81] =?UTF-8?q?im=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D-re?= =?UTF-8?q?dis=E7=BB=9F=E4=B8=80key=EF=BC=8C=E4=BF=9D=E8=AF=81=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E6=9C=8D=E5=8A=A1=E5=99=A8=E4=BF=9D=E5=AD=98=E7=9B=B8?= =?UTF-8?q?=E5=90=8C=E7=9A=84=E5=AE=A2=E6=9C=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/service/DistributedSessionService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedSessionService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedSessionService.java index 0533feb0..2813fb87 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedSessionService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedSessionService.java @@ -24,7 +24,7 @@ public class DistributedSessionService { private static final String USER_SERVER_KEY = "im:user:server:"; private static final String USER_SESSIONS_KEY = "im:user:sessions:"; - private static final String SERVER_USERS_KEY = "im:server:users:"; + private static final String SERVER_USERS_KEY = "im:server:users:kf"; private static final String GROUP_SESSIONS_KEY = "im:group:sessions:"; /** @@ -33,7 +33,7 @@ public class DistributedSessionService { public void registerUserSession(String userId, String sessionId, Map attributes) { String userKey = USER_SESSIONS_KEY + userId; String serverKey = USER_SERVER_KEY + userId; - String serverUsersKey = SERVER_USERS_KEY + getServerId(); + String serverUsersKey = SERVER_USERS_KEY; // 存储用户会话信息 Map sessionInfo = new HashMap<>(); @@ -61,7 +61,7 @@ public class DistributedSessionService { */ public void unregisterUserSession(String userId, String sessionId) { String userKey = USER_SESSIONS_KEY + userId; - String serverUsersKey = SERVER_USERS_KEY + getServerId(); + String serverUsersKey = SERVER_USERS_KEY; // 从用户会话中移除 redisTemplate.opsForHash().delete(userKey, sessionId); @@ -146,7 +146,7 @@ public class DistributedSessionService { */ public List getOnlineUserIds() { // 方法1: 通过服务器用户集合获取(推荐) - String serverUsersKey = SERVER_USERS_KEY + getServerId(); + String serverUsersKey = SERVER_USERS_KEY; Set userIds = redisTemplate.opsForSet().members(serverUsersKey); if (userIds != null && !userIds.isEmpty()) { From da449a59215a9aac535130775f02aa5cc70ce387 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 19 Nov 2025 08:29:03 +0800 Subject: [PATCH 02/81] =?UTF-8?q?=E7=A0=8D=E4=BB=B7=E8=B6=85=E6=97=B6?= =?UTF-8?q?=E6=97=B6=E9=97=B4=EF=BC=8C=E8=B5=8B=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/page/service/impl/ShopPageAppServiceImpl.java | 3 +-- .../service/impl/ShopStoreActivityBaseServiceImpl.java | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java index 44d32165..369de289 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java @@ -119,7 +119,7 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl Date: Wed, 19 Nov 2025 10:59:08 +0800 Subject: [PATCH 03/81] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=B8=8B=E5=8D=95?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=BB=99=E6=80=9D=E8=BF=85=E6=B5=81=E6=B0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sync/ProductQuantityConsumption.java | 4 ++++ .../impl/ShopOrderReturnServiceImpl.java | 16 +++++++++++--- .../service/impl/SFExpressApiServiceImpl.java | 14 ++++++++++-- .../impl/SyncThirdDataServiceImpl.java | 22 ++++++++++++++----- sql/shop/dev/20251119_dml.sql | 1 + 5 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 sql/shop/dev/20251119_dml.sql diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/sync/ProductQuantityConsumption.java b/mall-common/src/main/java/com/suisung/mall/common/modules/sync/ProductQuantityConsumption.java index 08f5bc07..6145dfc6 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/sync/ProductQuantityConsumption.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/sync/ProductQuantityConsumption.java @@ -57,4 +57,8 @@ public class ProductQuantityConsumption { @ApiModelProperty(value = "更新时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; + + @TableField(value = "sale_time",updateStrategy = FieldStrategy.NOT_EMPTY) + @ApiModelProperty(value = "下单时间") + private Long saleTime; } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index d1b6066e..47b7a73f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1580,7 +1580,13 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl returnItemQueryWrapper = new QueryWrapper<>(); returnItemQueryWrapper.in("return_id", return_ids); List returnItems = orderReturnItemService.find(returnItemQueryWrapper); - + QueryWrapper shopOrderReturnQueryWrapper= new QueryWrapper<>(); + shopOrderReturnQueryWrapper.in("return_id", return_ids); + List shopOrderReturnList= shopOrderReturnService.find(shopOrderReturnQueryWrapper); + Map shopOrderReturnMap=new HashMap<>(); + if(!shopOrderReturnList.isEmpty()){ + shopOrderReturnMap=shopOrderReturnList.stream().collect(Collectors.toMap(ShopOrderReturn::getReturn_id, s->s.getUpdated_at().getTime())); + } if (CollUtil.isNotEmpty(returnItems)) { for (ShopOrderReturnItem returnItem : returnItems) { String order_id = returnItem.getOrder_id(); @@ -1631,9 +1637,13 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - stockDeltaMap.put(item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getItem_unit_price(), returnNum); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getItem_unit_price(); + if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ + mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id()); + } + stockDeltaMap.put(mapKey, returnNum); syncThirdDataService.incrProductStockToRedis(stockDeltaMap, returnItem.getReturn_item_subtotal()); - logger.info("退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{}", item_src_id, shopOrderReturn.getOrder_id(), returnNum); + logger.info("退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{},mapKey:{}", item_src_id, shopOrderReturn.getOrder_id(), returnNum,mapKey); } else { logger.warn("退货数量为空,无法增加库存,订单项ID: {}", orderItemId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java index 25160b6c..f4a4f1c4 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java @@ -1170,6 +1170,11 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { String order_id = shopStoreSfOrder.getShop_order_id(); itemQueryWrapper.eq("order_id", order_id); List order_item_rows = shopOrderItemService.find(itemQueryWrapper); + ShopOrderBase shopOrderBase=shopOrderBaseService.get(order_id); + String saleTimeStr=null; + if(null!=shopOrderBase){ + saleTimeStr= String.valueOf(shopOrderBase.getOrder_time().getTime()); + } if (picking(order_item_rows)) { logger.info("顺丰发货商品扣减库存成功"); } @@ -1178,7 +1183,11 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - stockDeltaMap.put(item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getItem_unit_price(), -order_item_quantity); + String mapKey=item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getItem_unit_price(); + if(StringUtils.isNotEmpty(saleTimeStr)){ + mapKey=mapKey+"-"+saleTimeStr; + } + stockDeltaMap.put(mapKey, -order_item_quantity); syncThirdDataService.incrProductStockToRedis(stockDeltaMap,null); } } @@ -1347,7 +1356,8 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - stockDeltaMap.put(item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getItem_unit_price(), -order_item_quantity); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getItem_unit_price()+"-"+shopOrderBase.getOrder_time().getTime(); + stockDeltaMap.put(mapKey, -order_item_quantity); syncThirdDataService.incrProductStockToRedis(stockDeltaMap,null); } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java index 1144d7c8..ddff290b 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java @@ -989,13 +989,16 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements ProductQuantityConsumption productQuantityConsumption=new ProductQuantityConsumption(); String productKey= (String) k; String[] productKeyArrys=productKey.split("-"); - if(productKeyArrys.length!=4){ + if(productKeyArrys.length<4){ return; } String productNumber=productKeyArrys[0]; String orderId=productKeyArrys[1]; String unitPrice=productKeyArrys[2]; String saleAmount=productKeyArrys[3]; + if(productKeyArrys.length==5){ + productQuantityConsumption.setSaleTime(Long.parseLong(productKeyArrys[4])); + } productQuantityConsumption.setConsumeId(IdUtil.getSnowflakeNextIdStr()); productQuantityConsumption.setOrderId(orderId); productQuantityConsumption.setProductNumber(productNumber); @@ -1027,7 +1030,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements continue; } String[] productKeyArrys=productKey.split("-"); - if(productKeyArrys.length!=3){ + if(productKeyArrys.length<3){ continue; } try { @@ -1063,12 +1066,17 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements cn.hutool.json.JSONArray array_item_spec = JSONUtil.parseArray(spuItem.getItem_spec()); logger.info("array_item_spec:{}",array_item_spec); logger.info("key:{},Product_number:{}",key,itemId); + String mapKey=""; if(array_item_spec.isEmpty()){ BigDecimal saleAmount=new BigDecimal(unitPrice).multiply(new BigDecimal(delta)); if(saleAmount.compareTo(BigDecimal.ZERO)<0){ saleAmount=saleAmount.multiply(new BigDecimal("-1")); } - redisTemplate.opsForHash().increment(key, itemId+"-"+orderId+"-"+unitPrice+"-"+saleAmount.toPlainString(), delta.doubleValue()); + mapKey=itemId+"-"+orderId+"-"+unitPrice+"-"+saleAmount.toPlainString(); + if(productKeyArrys.length==4){ + mapKey=mapKey+"-"+productKeyArrys[3]; + } + redisTemplate.opsForHash().increment(key,mapKey, delta.doubleValue()); logger.info("存储无规格库存成功"); continue; } @@ -1089,8 +1097,12 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements itemReturnAmount=itemReturnAmount.multiply(new BigDecimal("-1")); } // 使用 Redis 的 HINCRBY 保证原子性和高性能 - redisTemplate.opsForHash().increment(key, itemId+"-"+orderId+"-"+unitPriceBg.toPlainString()+"-"+itemReturnAmount.toPlainString(), itemQuaryty.doubleValue()); - logger.info("存储有规格库存成功",itemId+"-"+orderId+"-"+unitPriceBg.toPlainString()); + mapKey=itemId+"-"+orderId+"-"+unitPriceBg.toPlainString()+"-"+itemReturnAmount.toPlainString(); + if(productKeyArrys.length==4){ + mapKey=mapKey+"-"+productKeyArrys[3]; + } + redisTemplate.opsForHash().increment(key, mapKey, itemQuaryty.doubleValue()); + logger.info("存储有规格库存成功mapKey:{},",mapKey); } catch (Exception e) { logger.error("库存累计失败,productKey={}, delta={}, error={}", productKey, delta, e.getMessage(), e); } diff --git a/sql/shop/dev/20251119_dml.sql b/sql/shop/dev/20251119_dml.sql new file mode 100644 index 00000000..8e3473b8 --- /dev/null +++ b/sql/shop/dev/20251119_dml.sql @@ -0,0 +1 @@ +ALTER table product_quantity_consumption add sale_time bigint unsigned DEFAULT NULL COMMENT '下单时间'; \ No newline at end of file From 7dd3822e4495f50490787bca821154dddec15ad1 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 19 Nov 2025 15:14:53 +0800 Subject: [PATCH 04/81] =?UTF-8?q?im=E8=BF=98=E5=8E=9F=E5=8D=95=E6=9C=BA?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onchat/MallsuiteImSocketHandler.java | 476 +++++++++++------- 1 file changed, 289 insertions(+), 187 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index 5d35d14b..82ed6eb2 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -1,11 +1,11 @@ package com.suisung.mall.im.common.websocket.service.onchat; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; import cn.hutool.json.JSONUtil; -import com.suisung.mall.im.common.websocket.service.DistributedMessageService; -import com.suisung.mall.im.common.websocket.service.DistributedSessionService; -import com.suisung.mall.im.common.websocket.service.LocalSessionManager; +import com.suisung.mall.common.feignService.AccountService; +import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.im.common.websocket.utils.Constants; import com.suisung.mall.im.pojo.entity.ChatHistory; import com.suisung.mall.im.pojo.vo.MineDTO; @@ -13,77 +13,164 @@ import com.suisung.mall.im.pojo.vo.ReceiveDTO; import com.suisung.mall.im.pojo.vo.SendVO; import com.suisung.mall.im.pojo.vo.ToDTO; import com.suisung.mall.im.service.ChatHistoryService; +import com.suisung.mall.im.service.LayGroupService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; - import org.springframework.web.socket.*; import java.io.IOException; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; public class MallsuiteImSocketHandler implements WebSocketHandler { private static Logger logger = LoggerFactory.getLogger(MallsuiteImSocketHandler.class); - // 移除原有的静态集合,使用注入的服务 - // private static ArrayList users; - // private static ArrayList usersStr; - // private static Map> userSession; - // private static Map> groupSession; + private static ArrayList users; + private static ArrayList usersStr; - @Autowired - private DistributedSessionService distributedSessionService; + //存入用户的所有终端的连接信息 + private static Map> userSession; - @Autowired - private DistributedMessageService distributedMessageService; + //群组信息 + private static Map> groupSession; - @Autowired - private LocalSessionManager localSessionManager; + static { + users = new ArrayList<>(); + usersStr = new ArrayList<>(); + userSession = Collections.synchronizedMap(new HashMap<>()); + groupSession = Collections.synchronizedMap(new HashMap<>()); + logger = LoggerFactory.getLogger(MallsuiteImSocketHandler.class); + } + + public ArrayList getOnlineLoginNames() { + ArrayList onlineLoginNames = new ArrayList(); + for (WebSocketSession user : users) { + String userName = (String) user.getAttributes().get(Constants.WEBSOCKET_LOGINNAME); + if (userName != null) { + onlineLoginNames.add(userName); + } + } + return onlineLoginNames; + + } + + public ArrayList getOnlineLoginUserId() { + ArrayList onlineLoginUserId = new ArrayList(); + for (WebSocketSession user : users) { + Integer user_id = Convert.toInt(user.getAttributes().get("user_id")); + if (CheckUtil.isNotEmpty(user_id)) { + onlineLoginUserId.add(user_id); + } + } + return onlineLoginUserId; + + } @Autowired private ChatHistoryService chatHistoryService; - + @Autowired + private LayGroupService layGroupService; + @Autowired + private AccountService accountService; //用户上线后触发 @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.debug("connect to the websocket success......"); - - String loginUserId = String.valueOf(session.getAttributes().get("user_id")) ; String sessionId = session.getId(); + users.add(session); + this.updateOnlineStatus(); + String loginUserId = (String) session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME);//获取刚上线用户的loginName - // 存储到本地会话管理 - ConcurrentHashMap> userSessions=new ConcurrentHashMap<>(); - localSessionManager.setUserSessions(userSessions); - localSessionManager.addUserSession(loginUserId, session); + List loginSessions = userSession.get(loginUserId); + if (CollUtil.isEmpty(loginSessions)) { + if (null == loginSessions) { + loginSessions = new ArrayList<>(); + } - logger.info("添加会话到本地成功:{}", localSessionManager.getUserSessions().values()); + loginSessions.add(session); + userSession.put(loginUserId, loginSessions); + } else { + if (!loginSessions.contains(session)) { + loginSessions.add(session); + } + } - // 注册到分布式会话服务 - Map attributes = new HashMap<>(); - attributes.put("user_id", String.valueOf(session.getAttributes().get("user_id"))); - attributes.put("loginName", loginUserId); - distributedSessionService.registerUserSession(loginUserId, sessionId, attributes); + if (loginUserId != null) { + SendVO msg = new SendVO(); + //读取离线信息 + ChatHistory chat = new ChatHistory(); + chat.setReceiver(loginUserId);//发给刚上线的用户信息 + chat.setStatus("0"); + List list = chatHistoryService.findList(chat); + /* + for(ChatHistory c : list){ + String sender=""; + String receiver=""; - // 处理离线消息等原有逻辑... - // this.updateOnlineStatus(); + if("friend".equals(c.getType()) || "user".equals(c.getType())){//如果是个人信息 + sender = c.getSender(); //todo 确认数据库存的数据uid user_id 不一致 + msg.setId(sender); + msg.setToid(c.getReceiver()); + msg.setContent(c.getMsg()); + //todu 缺少数据 + //msg = sender+Constants._msg_+c.getReceiver()+Constants._msg_+c.getMsg()+Constants._msg_; + }else if(c.getType().contains("_group")){//如果是直播群组信息 + msg.setType("group"); + sender = c.getSender(); + String groupId = c.getReceiver().split("_")[0];//直播群组id + receiver=c.getReceiver().split("_")[1];//直播群组所属user_id + msg = sender+Constants._msg_+groupId+Constants._msg_+c.getMsg()+Constants._msg_; + + }else{//如果是群组信息 + msg.setType("group"); + + String groupId = c.getSender().split(Constants._msg_)[0];//群组id + sender=c.getSender().split(Constants._msg_)[1];//发送者loginName + msg = groupId+Constants._msg_+c.getReceiver()+Constants._msg_+c.getMsg()+Constants._msg_; + + } + + //todo 应该冗余 + //获取用户基本信息 + AccountUserBase accountUserBase = accountService.getUserBase(Integer.valueOf(sender)); + //AccountUserBase accountUserBase= result.getFenResult(AccountUserBase.class); + //AccountUserInfo userInfo=accountService.getUserInfo(accountUserBase.getUser_id()); + AccountUserInfo userInfo=accountService.getUserInfo(Integer.valueOf(sender)); + + + msg.setUser_id(Convert.toInt(session.getAttributes().get("user_id"))); + msg.setUsername(accountUserBase.getUser_nickname()); + msg.setAvatar(userInfo.getUser_avatar()); + //msg.setMessage_id(c.getId()); + msg.setFromid(msg.getId()); + msg.setTime(c.getCreate_date().getTime()); + msg.setStatus(0); //? + msg.setMsg(new HashMap()); + + boolean isSuccess = this.sendMessageToUser(loginUserId, msg); + if(isSuccess) { + c.setStatus("1");//标记为已读 + chatHistoryService.saveNew(c); + } + } + */ + } } //接收js侧发送来的用户信息 @Override public void handleMessage(WebSocketSession session, WebSocketMessage socketMessage) throws Exception { ReceiveDTO receiveDTO = JSONUtil.toBean(socketMessage.getPayload().toString(), ReceiveDTO.class); - if (receiveDTO != null) { + if (receiveDTO != null) {//发送消息 SendVO sendVO = new SendVO(); MineDTO mine = receiveDTO.getMine(); ToDTO to = receiveDTO.getTo(); - // 设置sendVO的代码保持不变... sendVO.setToid(to.getId()); - sendVO.setZid(to.getZid()); + sendVO.setZid(to.getZid()); //群组特有 sendVO.setId(mine.getId()); Integer toUserId = Convert.toInt(session.getAttributes().get("user_id")); sendVO.setUser_id(toUserId); @@ -95,33 +182,32 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { to.setType("friend"); } - sendVO.setType(to.getType()); + sendVO.setType(to.getType()); //是从to中读取Type sendVO.setSendmethod(sendVO.getType()); + sendVO.setContent(mine.getContent()); sendVO.setMessage_id(mine.getMessage_id()); + sendVO.setFromid(mine.getId()); sendVO.setTime(new Date().getTime()); - sendVO.setStatus(0); + sendVO.setStatus(0); //? sendVO.setMsg_type(mine.getType()); sendVO.setItem_id(mine.getItem_id()); sendVO.setMsg(new HashMap()); sendVO.setMessage_length(mine.getLength()); - String sender = mine.getId(); - String receiver = to.getId(); + String sender = mine.getId();//信息发送者登录名(loginName)或user_id + String receiver = to.getId();//信息接收者,如果是私聊就是用户loginName,如果是群聊就是群组id String msg = mine.getContent(); String avatar = mine.getAvatar(); String type = to.getType(); - String senderName = mine.getUsername(); - - // 更新心跳 - distributedSessionService.updateHeartbeat(sender, session.getId()); + String senderName = mine.getUsername();//发送者姓名(name) if (!mine.getId().equals(to.getId())) { sendVO.setMine(false); - + //保存聊天记录 if ("friend".equals(type) || "user".equals(type)) { - // 私聊消息 - 使用分布式发送 + //如果是私聊 ChatHistory chat = new ChatHistory(); chat.setId(IdUtil.simpleUUID()); chat.setSender(sender); @@ -129,49 +215,124 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { chat.setMsg(msg); chat.setType("friend"); chat.setCreate_date(new Date()); - - boolean isSuccess = distributedMessageService.sendToUser(receiver, sendVO); - if (isSuccess) { - chat.setStatus("1"); + boolean isSuccess = this.sendMessageToUser(receiver, sendVO); + if (isSuccess) {//如果信息发送成功 + chat.setStatus("1");//设置为已读 } else { - // 发送离线消息提醒 sendVO.setToid(mine.getId()); sendVO.setContent(to.getName() + " 对方现在离线,他将在上线后收到你的消息!"); sendVO.setMsg_type("text"); sendVO.setMessage_length("0"); sendVO.setId(to.getId()); - distributedMessageService.sendToUser(sender, sendVO); - chat.setStatus("0"); + this.sendMessageToUser(sender, sendVO);//同时向本人发送对方不在线消息 + chat.setStatus("0");//设置为未读 } chatHistoryService.saveNew(chat); + } else if ("group".equals(type)) {//如果是群聊 + // 临时,不经过数据库 + List groupLoginSession = groupSession.get(to.getZid()); - } else if ("group".equals(type)) { - // 群聊消息 - 使用分布式发送 - String groupId = to.getZid(); - distributedMessageService.sendToGroup(groupId, sendVO, session.getId()); + if (!CollUtil.isEmpty(groupLoginSession)) { + for (WebSocketSession gs : groupLoginSession) { - } else if ("join_group".equals(type)) { - // 加入群组 + if (sender.equals(gs.getAttributes().get(Constants.WEBSOCKET_LOGINNAME).toString())) {//群消息不发给自己,但是存一条记录当做聊天记录查询 + + } else { + //设置接受用户 + sendVO.setToid(gs.getAttributes().get(Constants.WEBSOCKET_LOGINNAME).toString()); + boolean isSuccess = this.sendMessageToUser(to.getName(), sendVO); + if (isSuccess) { + + } else { + } + } + + //chatHistoryService.saveNew(chat); + } + } + + + /* + List layGroupUserlist = new ArrayList(); + + //群主 + LayGroupUser owner = new LayGroupUser(); + LayGroup layGroup = layGroupService.get(receiver); + owner.setUser_id(layGroup.getCreate_by()); + layGroupUserlist.add(owner); + + //群成员1 + List zlist = layGroupService.getUsersByGroup(layGroupService.get(receiver)); + layGroupUserlist.addAll(zlist); + + for (LayGroupUser lgUser : layGroupUserlist) { + AccountUserBase user_base_row = accountService.getUserBase(Integer.valueOf(lgUser.getUser_id())); + ChatHistory chat = new ChatHistory(); + chat.setId(IdUtil.simpleUUID()); + //群聊时信息先发送给群聊id(即receiver),在后台转发给所有非发送者(sender)的人的话,群聊id(即receiver)就变成发送者。 + String groupId = receiver; + //保存聊天记录 + chat.setSender(groupId + Constants._msg_ + sender);//群聊时保存群聊id和发送者id + chat.setReceiver(user_base_row.getUser_account());//群中所有信息获得者人员 + chat.setMsg(msg); + chat.setType("group"); + //message = groupId + Constants._msg_ + user_base_row.getUser_account() + Constants._msg_ + msg + Constants._msg_ + avatar + Constants._msg_ + type + Constants._msg_ + senderName + Constants._msg_ + datatime; + if (sender.equals(user_base_row.getUser_account())) {//群消息不发给自己,但是存一条记录当做聊天记录查询 + chat.setStatus("1");//发送成功,设置为已读 + } else { + boolean isSuccess = this.sendMessageToUser(user_base_row.getUser_account(), sendVO); + if (isSuccess) { + chat.setStatus("1");//发送成功,设置为已读 + } else { + chat.setStatus("0");//用户不在线,设置为未读 + } + } + + chatHistoryService.saveNew(chat); + } + */ + + } else if ("join_group".equals(type)) { //临时群组,聚焦当前窗口 String zid = to.getZid(); + + //设置session,属性上标出所属群组: 目前无同时多个群组需求,如果存在,此处存入list session.getAttributes().put(Constants.WEBSOCKET_GROUP_KEY, zid); - // 添加到本地群组 - localSessionManager.addGroupSession(zid, session); + //设置群组中用户 + List groupLoginSession = groupSession.get(zid); - // 添加到分布式群组 - String userId = (String) session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME); - distributedSessionService.addUserToGroup(zid, userId, session.getId()); + if (CollUtil.isEmpty(groupLoginSession)) { + if (null == groupLoginSession) { + groupLoginSession = new ArrayList<>(); + } - } else if ("leave_group".equals(type)) { - // 离开群组 + groupLoginSession.add(session); + groupSession.put(zid, groupLoginSession); + } else { + if (!groupLoginSession.contains(session)) { + groupLoginSession.add(session); + } + } + + //todo通知已存在群组用户消息 可启动独立task + } else if ("leave_group".equals(type)) { //临时群组,聚焦当前窗口 String zid = to.getZid(); + + //设置session,属性上标出所属群组 session.getAttributes().put(Constants.WEBSOCKET_GROUP_KEY, null); - // 从本地群组移除 - localSessionManager.removeGroupSession(zid, session); + //设置群组中用户 + List groupLoginSession = groupSession.get(zid); - // 从分布式群组移除 - distributedSessionService.removeUserFromGroup(zid, session.getId()); + if (CollUtil.isEmpty(groupLoginSession)) { + } else { + if (groupLoginSession.contains(session)) { + groupLoginSession.remove(session); + } + } + + //todo通知已存在群组用户消息 可启动独立task + } else { } } else { sendVO.setMine(true); @@ -185,39 +346,28 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { session.close(); } logger.debug("websocket connection closed......"); - cleanupSession(session); + users.remove(session); + userSession.get(session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME)).remove(session); + + if (CollUtil.isNotEmpty(groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)))) { + groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)).remove(session); + } + + this.updateOnlineStatus(); + } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { logger.debug("websocket connection closed......"); - cleanupSession(session); - } + users.remove(session); + userSession.get(session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME)).remove(session); - /** - * 清理会话资源 - */ - private void cleanupSession(WebSocketSession session) { - String loginUserId = String.valueOf(session.getAttributes().get("user_id")) ; - String sessionId = session.getId(); - String groupId = (String) session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY); - - // 从本地管理移除 - if(localSessionManager.getUserSessions()==null){ - localSessionManager.setUserSessions(new ConcurrentHashMap<>()); - } - localSessionManager.removeUserSession(loginUserId, session); - if (groupId != null) { - localSessionManager.removeGroupSession(groupId, session); + if (CollUtil.isNotEmpty(groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)))) { + groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)).remove(session); } - // 从分布式存储注销 - distributedSessionService.unregisterUserSession(loginUserId, sessionId); - if (groupId != null) { - distributedSessionService.removeUserFromGroup(groupId, sessionId); - } - - // this.updateOnlineStatus(); + this.updateOnlineStatus(); } @Override @@ -226,112 +376,64 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { } /** - * 给某个用户发送消息 (兼容原有接口) + * 给所有在线用户发送消息 + * + * @param message */ - public boolean sendMessageToUser(String loginName, SendVO message) { - return distributedMessageService.sendToUser(loginName, message); - } + public void sendMessageToAllUsers(List message) { - /** - * 获取所有在线用户登录名 - */ - public List getOnlineLoginNames() { - // 使用分布式服务获取所有在线用户登录名 - return distributedSessionService.getOnlineLoginNames(); - } + SendVO msg = new SendVO(); + msg.setContent(message.toString()); + msg.setType("online"); + msg.setSendmethod(msg.getType()); - /** - * 获取所有在线用户ID - */ - public List getOnlineLoginUserId() { - // 使用分布式服务获取所有在线用户ID - return distributedSessionService.getAllOnlineUserIds(); - } - - /** - * 获取当前服务器的在线用户ID - */ - public List getLocalOnlineLoginUserId() { - // 使用本地会话管理器获取当前服务器的在线用户ID - return localSessionManager.getLocalOnlineUserIds(); - } - - /** - * 获取当前服务器的在线用户登录名 - */ - public List getLocalOnlineLoginNames() { - // 使用本地会话管理器获取当前服务器的在线用户登录名 - return localSessionManager.getLocalOnlineLoginNames(); - } - - /** - * 更新在线状态 - 通知所有用户在线列表变化 - */ - public void updateOnlineStatus() { - try { - // 创建在线状态消息 - SendVO onlineStatusMsg = new SendVO(); - onlineStatusMsg.setType("online_status"); - onlineStatusMsg.setSendmethod("broadcast"); - - // 获取在线用户列表 - List onlineUsers = getOnlineLoginNames(); - List onlineUserIds = getOnlineLoginUserId(); - - Map data = new HashMap<>(); - data.put("onlineUsers", onlineUsers); - data.put("onlineUserIds", onlineUserIds); - data.put("timestamp", System.currentTimeMillis()); - - onlineStatusMsg.setMsg(data); - - // 广播在线状态更新(只广播到当前服务器,避免循环广播) - broadcastLocalOnlineStatus(onlineStatusMsg); - - logger.info("在线状态更新: {} 个用户在线", onlineUsers.size()); - } catch (Exception e) { - logger.error("更新在线状态失败: " + e.getMessage(), e); - } - } - - /** - * 广播在线状态到本地用户 - */ - private void broadcastLocalOnlineStatus(SendVO message) { - logger.info("localSessionManager: {}", localSessionManager); - logger.info("localSessionManager.userSessions: {}", localSessionManager.getUserSessions()); - logger.info("localSessionManager.userSessions.values: {}", localSessionManager.getUserSessions().values()); - if (localSessionManager == null || localSessionManager.getUserSessions().isEmpty()) { - logger.error("localSessionManager is null, cannot broadcast online status"); - return; - } - - // 获取本地所有用户会话 - for (List sessions : localSessionManager.getUserSessions().values()) { - for (WebSocketSession session : sessions) { - if (session!=null&&session.isOpen()) { - try { - session.sendMessage(new TextMessage(message.toString())); - } catch (IOException e) { - logger.error("发送在线状态消息失败: " + e.getMessage(), e); - } + //不能这么操作 + for (WebSocketSession user : users) { + try { + if (user.isOpen()) { + user.sendMessage(new TextMessage(msg.toString())); } + } catch (IOException e) { + logger.error("给所有在线用户发送信息失败!" + e.getMessage(), e); } } } /** - * 给所有在线用户发送消息 + * 给某个用户发送消息 + * + * @param loginName + * @param message */ - public void sendMessageToAllUsers(SendVO message) { - // 获取所有在线用户ID - List onlineUserIds = getOnlineLoginUserId(); + public boolean sendMessageToUser(String loginName, SendVO message) { + boolean result = false; - for (Integer userId : onlineUserIds) { - String userIdStr = String.valueOf(userId); - distributedMessageService.sendToUser(userIdStr, message); + //不能这样操作。 + //for (WebSocketSession user : users) { + List lst = userSession.get(message.getToid()); + + if (CollUtil.isNotEmpty(lst)) { + for (WebSocketSession user : lst) { + //if (user.getAttributes().get(Constants.WEBSOCKET_LOGINNAME).equals(loginName)) {//允许用户多个浏览器登录,每个浏览器页面都会收到用户信息 + try { + if (user.isOpen()) { + user.sendMessage(new TextMessage(message.toString())); + result = true; + } + } catch (IOException e) { + logger.error("给用户发送信息失败!" + e.getMessage(), e); + } + + //break;//注释掉此处意味着遍历该用户打开的所有页面并发送信息,否则只会向用户登录的第一个网页发送信息。 + //} + } } - logger.debug("向 {} 个在线用户发送消息", onlineUserIds.size()); + return result; } + + public void updateOnlineStatus() { + //this.sendMessageToAllUsers(this.getOnlineLoginNames());//通知所有用户更新在线信息 + } + } \ No newline at end of file From 928b16da60d36f5aa95e9b611b88d871be9d4aa8 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 19 Nov 2025 15:18:17 +0800 Subject: [PATCH 05/81] =?UTF-8?q?im=E8=BF=98=E5=8E=9F=E5=8D=95=E6=9C=BA?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/im/controller/admin/ChatSocketInfoController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java b/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java index dc36e35c..dd4bb67d 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java +++ b/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java @@ -45,7 +45,8 @@ public class ChatSocketInfoController { @RequestMapping(value = "/getUserOnline", method = RequestMethod.POST) public List getUserOnline(@RequestBody List user_ids) { logger.info(I18nUtil._("接收的用户ids:") + CollUtil.join(user_ids, ",")); - List onlineLoginUserIds = distributedSessionService.getOnlineUserIds(); + //List onlineLoginUserIds = distributedSessionService.getOnlineUserIds(); + List onlineLoginUserIds = new MallsuiteImSocketHandler().getOnlineLoginUserId(); Iterator online_user_ids_iter = onlineLoginUserIds.iterator(); // 处理移除非本店铺客服 while (online_user_ids_iter.hasNext()) { From 8c9661c77c5ce8672e97b25ea4c376c4fb0c35a7 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 19 Nov 2025 16:16:44 +0800 Subject: [PATCH 06/81] =?UTF-8?q?im=E5=88=86=E5=B8=83=E5=BC=8F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/DistributedMessageService.java | 10 +- .../service/LocalSessionManager.java | 14 +- .../service/MessageConsumerService.java | 2 +- .../onchat/MallsuiteImSocketHandler.java | 476 +++++++----------- .../admin/ChatSocketInfoController.java | 4 +- 5 files changed, 207 insertions(+), 299 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java index 230fb31f..74175b2f 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java @@ -1,13 +1,17 @@ package com.suisung.mall.im.common.websocket.service; import com.suisung.mall.im.pojo.vo.SendVO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.socket.WebSocketSession; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import static com.suisung.mall.im.common.websocket.config.RabbitMQConfig.IM_FANOUT_EXCHANGE; @@ -15,6 +19,7 @@ import static com.suisung.mall.im.common.websocket.config.RabbitMQConfig.IM_FANO @Service public class DistributedMessageService { + private static final Logger log = LoggerFactory.getLogger(DistributedMessageService.class); @Autowired private RabbitTemplate rabbitTemplate; @@ -30,7 +35,8 @@ public class DistributedMessageService { /** * 发送消息给用户 */ - public boolean sendToUser(String targetUserId, SendVO message) { + public boolean sendToUser(String targetUserId, SendVO message, ConcurrentHashMap> userSessions) { + log.info("targetUserId{},message:{}", targetUserId, message); String targetServer = sessionService.getUserServer(targetUserId); if (targetServer == null) { @@ -40,7 +46,7 @@ public class DistributedMessageService { if (isCurrentServer(targetServer)) { // 用户在当前服务器,直接发送 - return localSessionManager.sendToUser(targetUserId, message); + return localSessionManager.sendToUser(targetUserId, message,userSessions); } else { // 用户在其他服务器,通过RabbitMQ转发 forwardToUser(targetServer, targetUserId, message); diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java index 4e7ab0e6..c9f845b6 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java @@ -42,9 +42,10 @@ public class LocalSessionManager { if (existingSessions == null) { existingSessions = new CopyOnWriteArrayList<>(); } - if (!existingSessions.contains(session)) { - existingSessions.add(session); - } +// if (!existingSessions.contains(session)) { +// existingSessions.add(session); +// } + existingSessions.add(session); return existingSessions; }); @@ -68,12 +69,15 @@ public class LocalSessionManager { /** * 发送消息给用户 */ - public boolean sendToUser(String userId, SendVO message) { + public boolean sendToUser(String userId, SendVO message,ConcurrentHashMap> userSession) { if (userId == null || message == null) { log.info("发送消息失败: 参数为空"); return false; } - + if(null!=userSession){ + this.userSessions=userSession; + } + log.info("userSessions={}", userSession); List sessions = userSessions.get(userId); if (sessions == null || sessions.isEmpty()) { log.info("用户没有活跃会话: {}", userId); diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java index 0cebeda6..155ada80 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java @@ -65,7 +65,7 @@ public class MessageConsumerService { } if (userMsg != null) { - boolean success = localSessionManager.sendToUser(userId, userMsg); + boolean success = localSessionManager.sendToUser(userId, userMsg,null); logger.info("发送消息给用户 {}: {}", userId, success ? "成功" : "失败"); } else { logger.info("消息格式错误,无法发送给用户: {}", userId); diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index 82ed6eb2..e4b11f83 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -1,11 +1,11 @@ package com.suisung.mall.im.common.websocket.service.onchat; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; import cn.hutool.json.JSONUtil; -import com.suisung.mall.common.feignService.AccountService; -import com.suisung.mall.common.utils.CheckUtil; +import com.suisung.mall.im.common.websocket.service.DistributedMessageService; +import com.suisung.mall.im.common.websocket.service.DistributedSessionService; +import com.suisung.mall.im.common.websocket.service.LocalSessionManager; import com.suisung.mall.im.common.websocket.utils.Constants; import com.suisung.mall.im.pojo.entity.ChatHistory; import com.suisung.mall.im.pojo.vo.MineDTO; @@ -13,164 +13,78 @@ import com.suisung.mall.im.pojo.vo.ReceiveDTO; import com.suisung.mall.im.pojo.vo.SendVO; import com.suisung.mall.im.pojo.vo.ToDTO; import com.suisung.mall.im.service.ChatHistoryService; -import com.suisung.mall.im.service.LayGroupService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.web.socket.*; import java.io.IOException; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; public class MallsuiteImSocketHandler implements WebSocketHandler { private static Logger logger = LoggerFactory.getLogger(MallsuiteImSocketHandler.class); - private static ArrayList users; - private static ArrayList usersStr; + // 移除原有的静态集合,使用注入的服务 + // private static ArrayList users; + // private static ArrayList usersStr; + // private static Map> userSession; + // private static Map> groupSession; - //存入用户的所有终端的连接信息 - private static Map> userSession; + @Autowired + private DistributedSessionService distributedSessionService; - //群组信息 - private static Map> groupSession; + @Autowired + private DistributedMessageService distributedMessageService; - static { - users = new ArrayList<>(); - usersStr = new ArrayList<>(); - userSession = Collections.synchronizedMap(new HashMap<>()); - groupSession = Collections.synchronizedMap(new HashMap<>()); - logger = LoggerFactory.getLogger(MallsuiteImSocketHandler.class); - } - - public ArrayList getOnlineLoginNames() { - ArrayList onlineLoginNames = new ArrayList(); - for (WebSocketSession user : users) { - String userName = (String) user.getAttributes().get(Constants.WEBSOCKET_LOGINNAME); - if (userName != null) { - onlineLoginNames.add(userName); - } - } - return onlineLoginNames; - - } - - public ArrayList getOnlineLoginUserId() { - ArrayList onlineLoginUserId = new ArrayList(); - for (WebSocketSession user : users) { - Integer user_id = Convert.toInt(user.getAttributes().get("user_id")); - if (CheckUtil.isNotEmpty(user_id)) { - onlineLoginUserId.add(user_id); - } - } - return onlineLoginUserId; - - } + @Autowired + private LocalSessionManager localSessionManager; @Autowired private ChatHistoryService chatHistoryService; - @Autowired - private LayGroupService layGroupService; - @Autowired - private AccountService accountService; + //用户上线后触发 @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.debug("connect to the websocket success......"); + + String loginUserId = String.valueOf(session.getAttributes().get("user_id")) ; String sessionId = session.getId(); - users.add(session); - this.updateOnlineStatus(); - String loginUserId = (String) session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME);//获取刚上线用户的loginName - List loginSessions = userSession.get(loginUserId); - if (CollUtil.isEmpty(loginSessions)) { - if (null == loginSessions) { - loginSessions = new ArrayList<>(); - } + // 存储到本地会话管理 + ConcurrentHashMap> userSessions=new ConcurrentHashMap<>(); + localSessionManager.setUserSessions(userSessions); + localSessionManager.addUserSession(loginUserId, session); - loginSessions.add(session); - userSession.put(loginUserId, loginSessions); - } else { - if (!loginSessions.contains(session)) { - loginSessions.add(session); - } - } + logger.info("添加会话到本地成功:{}", localSessionManager.getUserSessions().values()); - if (loginUserId != null) { - SendVO msg = new SendVO(); - //读取离线信息 - ChatHistory chat = new ChatHistory(); - chat.setReceiver(loginUserId);//发给刚上线的用户信息 - chat.setStatus("0"); - List list = chatHistoryService.findList(chat); - /* - for(ChatHistory c : list){ - String sender=""; - String receiver=""; + // 注册到分布式会话服务 + Map attributes = new HashMap<>(); + attributes.put("user_id", String.valueOf(session.getAttributes().get("user_id"))); + attributes.put("loginName", loginUserId); + distributedSessionService.registerUserSession(loginUserId, sessionId, attributes); - if("friend".equals(c.getType()) || "user".equals(c.getType())){//如果是个人信息 - sender = c.getSender(); //todo 确认数据库存的数据uid user_id 不一致 - msg.setId(sender); - msg.setToid(c.getReceiver()); - msg.setContent(c.getMsg()); - //todu 缺少数据 - //msg = sender+Constants._msg_+c.getReceiver()+Constants._msg_+c.getMsg()+Constants._msg_; - }else if(c.getType().contains("_group")){//如果是直播群组信息 - msg.setType("group"); + // 处理离线消息等原有逻辑... + // this.updateOnlineStatus(); - sender = c.getSender(); - String groupId = c.getReceiver().split("_")[0];//直播群组id - receiver=c.getReceiver().split("_")[1];//直播群组所属user_id - msg = sender+Constants._msg_+groupId+Constants._msg_+c.getMsg()+Constants._msg_; - - }else{//如果是群组信息 - msg.setType("group"); - - String groupId = c.getSender().split(Constants._msg_)[0];//群组id - sender=c.getSender().split(Constants._msg_)[1];//发送者loginName - msg = groupId+Constants._msg_+c.getReceiver()+Constants._msg_+c.getMsg()+Constants._msg_; - - } - - //todo 应该冗余 - //获取用户基本信息 - AccountUserBase accountUserBase = accountService.getUserBase(Integer.valueOf(sender)); - //AccountUserBase accountUserBase= result.getFenResult(AccountUserBase.class); - //AccountUserInfo userInfo=accountService.getUserInfo(accountUserBase.getUser_id()); - AccountUserInfo userInfo=accountService.getUserInfo(Integer.valueOf(sender)); - - - msg.setUser_id(Convert.toInt(session.getAttributes().get("user_id"))); - msg.setUsername(accountUserBase.getUser_nickname()); - msg.setAvatar(userInfo.getUser_avatar()); - //msg.setMessage_id(c.getId()); - msg.setFromid(msg.getId()); - msg.setTime(c.getCreate_date().getTime()); - msg.setStatus(0); //? - msg.setMsg(new HashMap()); - - boolean isSuccess = this.sendMessageToUser(loginUserId, msg); - if(isSuccess) { - c.setStatus("1");//标记为已读 - chatHistoryService.saveNew(c); - } - } - */ - } } //接收js侧发送来的用户信息 @Override public void handleMessage(WebSocketSession session, WebSocketMessage socketMessage) throws Exception { ReceiveDTO receiveDTO = JSONUtil.toBean(socketMessage.getPayload().toString(), ReceiveDTO.class); - if (receiveDTO != null) {//发送消息 + logger.info("接收到信息{}", receiveDTO); + if (receiveDTO != null) { SendVO sendVO = new SendVO(); MineDTO mine = receiveDTO.getMine(); ToDTO to = receiveDTO.getTo(); + // 设置sendVO的代码保持不变... sendVO.setToid(to.getId()); - sendVO.setZid(to.getZid()); //群组特有 + sendVO.setZid(to.getZid()); sendVO.setId(mine.getId()); Integer toUserId = Convert.toInt(session.getAttributes().get("user_id")); sendVO.setUser_id(toUserId); @@ -182,32 +96,33 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { to.setType("friend"); } - sendVO.setType(to.getType()); //是从to中读取Type + sendVO.setType(to.getType()); sendVO.setSendmethod(sendVO.getType()); - sendVO.setContent(mine.getContent()); sendVO.setMessage_id(mine.getMessage_id()); - sendVO.setFromid(mine.getId()); sendVO.setTime(new Date().getTime()); - sendVO.setStatus(0); //? + sendVO.setStatus(0); sendVO.setMsg_type(mine.getType()); sendVO.setItem_id(mine.getItem_id()); sendVO.setMsg(new HashMap()); sendVO.setMessage_length(mine.getLength()); - String sender = mine.getId();//信息发送者登录名(loginName)或user_id - String receiver = to.getId();//信息接收者,如果是私聊就是用户loginName,如果是群聊就是群组id + String sender = mine.getId(); + String receiver = to.getId(); String msg = mine.getContent(); String avatar = mine.getAvatar(); String type = to.getType(); - String senderName = mine.getUsername();//发送者姓名(name) + String senderName = mine.getUsername(); + + // 更新心跳 + distributedSessionService.updateHeartbeat(sender, session.getId()); if (!mine.getId().equals(to.getId())) { sendVO.setMine(false); - //保存聊天记录 + if ("friend".equals(type) || "user".equals(type)) { - //如果是私聊 + // 私聊消息 - 使用分布式发送 ChatHistory chat = new ChatHistory(); chat.setId(IdUtil.simpleUUID()); chat.setSender(sender); @@ -215,124 +130,48 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { chat.setMsg(msg); chat.setType("friend"); chat.setCreate_date(new Date()); - boolean isSuccess = this.sendMessageToUser(receiver, sendVO); - if (isSuccess) {//如果信息发送成功 - chat.setStatus("1");//设置为已读 + boolean isSuccess = distributedMessageService.sendToUser(receiver, sendVO,localSessionManager.getUserSessions()); + if (isSuccess) { + chat.setStatus("1"); } else { + // 发送离线消息提醒 sendVO.setToid(mine.getId()); sendVO.setContent(to.getName() + " 对方现在离线,他将在上线后收到你的消息!"); sendVO.setMsg_type("text"); sendVO.setMessage_length("0"); sendVO.setId(to.getId()); - this.sendMessageToUser(sender, sendVO);//同时向本人发送对方不在线消息 - chat.setStatus("0");//设置为未读 + distributedMessageService.sendToUser(sender, sendVO,localSessionManager.getUserSessions()); + chat.setStatus("0"); } chatHistoryService.saveNew(chat); - } else if ("group".equals(type)) {//如果是群聊 - // 临时,不经过数据库 - List groupLoginSession = groupSession.get(to.getZid()); - if (!CollUtil.isEmpty(groupLoginSession)) { - for (WebSocketSession gs : groupLoginSession) { + } else if ("group".equals(type)) { + // 群聊消息 - 使用分布式发送 + String groupId = to.getZid(); + distributedMessageService.sendToGroup(groupId, sendVO, session.getId()); - if (sender.equals(gs.getAttributes().get(Constants.WEBSOCKET_LOGINNAME).toString())) {//群消息不发给自己,但是存一条记录当做聊天记录查询 - - } else { - //设置接受用户 - sendVO.setToid(gs.getAttributes().get(Constants.WEBSOCKET_LOGINNAME).toString()); - boolean isSuccess = this.sendMessageToUser(to.getName(), sendVO); - if (isSuccess) { - - } else { - } - } - - //chatHistoryService.saveNew(chat); - } - } - - - /* - List layGroupUserlist = new ArrayList(); - - //群主 - LayGroupUser owner = new LayGroupUser(); - LayGroup layGroup = layGroupService.get(receiver); - owner.setUser_id(layGroup.getCreate_by()); - layGroupUserlist.add(owner); - - //群成员1 - List zlist = layGroupService.getUsersByGroup(layGroupService.get(receiver)); - layGroupUserlist.addAll(zlist); - - for (LayGroupUser lgUser : layGroupUserlist) { - AccountUserBase user_base_row = accountService.getUserBase(Integer.valueOf(lgUser.getUser_id())); - ChatHistory chat = new ChatHistory(); - chat.setId(IdUtil.simpleUUID()); - //群聊时信息先发送给群聊id(即receiver),在后台转发给所有非发送者(sender)的人的话,群聊id(即receiver)就变成发送者。 - String groupId = receiver; - //保存聊天记录 - chat.setSender(groupId + Constants._msg_ + sender);//群聊时保存群聊id和发送者id - chat.setReceiver(user_base_row.getUser_account());//群中所有信息获得者人员 - chat.setMsg(msg); - chat.setType("group"); - //message = groupId + Constants._msg_ + user_base_row.getUser_account() + Constants._msg_ + msg + Constants._msg_ + avatar + Constants._msg_ + type + Constants._msg_ + senderName + Constants._msg_ + datatime; - if (sender.equals(user_base_row.getUser_account())) {//群消息不发给自己,但是存一条记录当做聊天记录查询 - chat.setStatus("1");//发送成功,设置为已读 - } else { - boolean isSuccess = this.sendMessageToUser(user_base_row.getUser_account(), sendVO); - if (isSuccess) { - chat.setStatus("1");//发送成功,设置为已读 - } else { - chat.setStatus("0");//用户不在线,设置为未读 - } - } - - chatHistoryService.saveNew(chat); - } - */ - - } else if ("join_group".equals(type)) { //临时群组,聚焦当前窗口 + } else if ("join_group".equals(type)) { + // 加入群组 String zid = to.getZid(); - - //设置session,属性上标出所属群组: 目前无同时多个群组需求,如果存在,此处存入list session.getAttributes().put(Constants.WEBSOCKET_GROUP_KEY, zid); - //设置群组中用户 - List groupLoginSession = groupSession.get(zid); + // 添加到本地群组 + localSessionManager.addGroupSession(zid, session); - if (CollUtil.isEmpty(groupLoginSession)) { - if (null == groupLoginSession) { - groupLoginSession = new ArrayList<>(); - } + // 添加到分布式群组 + String userId = (String) session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME); + distributedSessionService.addUserToGroup(zid, userId, session.getId()); - groupLoginSession.add(session); - groupSession.put(zid, groupLoginSession); - } else { - if (!groupLoginSession.contains(session)) { - groupLoginSession.add(session); - } - } - - //todo通知已存在群组用户消息 可启动独立task - } else if ("leave_group".equals(type)) { //临时群组,聚焦当前窗口 + } else if ("leave_group".equals(type)) { + // 离开群组 String zid = to.getZid(); - - //设置session,属性上标出所属群组 session.getAttributes().put(Constants.WEBSOCKET_GROUP_KEY, null); - //设置群组中用户 - List groupLoginSession = groupSession.get(zid); + // 从本地群组移除 + localSessionManager.removeGroupSession(zid, session); - if (CollUtil.isEmpty(groupLoginSession)) { - } else { - if (groupLoginSession.contains(session)) { - groupLoginSession.remove(session); - } - } - - //todo通知已存在群组用户消息 可启动独立task - } else { + // 从分布式群组移除 + distributedSessionService.removeUserFromGroup(zid, session.getId()); } } else { sendVO.setMine(true); @@ -346,28 +185,39 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { session.close(); } logger.debug("websocket connection closed......"); - users.remove(session); - userSession.get(session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME)).remove(session); - - if (CollUtil.isNotEmpty(groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)))) { - groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)).remove(session); - } - - this.updateOnlineStatus(); - + cleanupSession(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { logger.debug("websocket connection closed......"); - users.remove(session); - userSession.get(session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME)).remove(session); + cleanupSession(session); + } - if (CollUtil.isNotEmpty(groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)))) { - groupSession.get(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)).remove(session); + /** + * 清理会话资源 + */ + private void cleanupSession(WebSocketSession session) { + String loginUserId = String.valueOf(session.getAttributes().get("user_id")) ; + String sessionId = session.getId(); + String groupId = (String) session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY); + + // 从本地管理移除 + if(localSessionManager.getUserSessions()==null){ + localSessionManager.setUserSessions(new ConcurrentHashMap<>()); + } + localSessionManager.removeUserSession(loginUserId, session); + if (groupId != null) { + localSessionManager.removeGroupSession(groupId, session); } - this.updateOnlineStatus(); + // 从分布式存储注销 + distributedSessionService.unregisterUserSession(loginUserId, sessionId); + if (groupId != null) { + distributedSessionService.removeUserFromGroup(groupId, sessionId); + } + + // this.updateOnlineStatus(); } @Override @@ -376,64 +226,112 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { } /** - * 给所有在线用户发送消息 - * - * @param message + * 给某个用户发送消息 (兼容原有接口) */ - public void sendMessageToAllUsers(List message) { + public boolean sendMessageToUser(String loginName, SendVO message) { + return distributedMessageService.sendToUser(loginName, message,localSessionManager.getUserSessions()); + } - SendVO msg = new SendVO(); - msg.setContent(message.toString()); - msg.setType("online"); - msg.setSendmethod(msg.getType()); + /** + * 获取所有在线用户登录名 + */ + public List getOnlineLoginNames() { + // 使用分布式服务获取所有在线用户登录名 + return distributedSessionService.getOnlineLoginNames(); + } - //不能这么操作 - for (WebSocketSession user : users) { - try { - if (user.isOpen()) { - user.sendMessage(new TextMessage(msg.toString())); + /** + * 获取所有在线用户ID + */ + public List getOnlineLoginUserId() { + // 使用分布式服务获取所有在线用户ID + return distributedSessionService.getAllOnlineUserIds(); + } + + /** + * 获取当前服务器的在线用户ID + */ + public List getLocalOnlineLoginUserId() { + // 使用本地会话管理器获取当前服务器的在线用户ID + return localSessionManager.getLocalOnlineUserIds(); + } + + /** + * 获取当前服务器的在线用户登录名 + */ + public List getLocalOnlineLoginNames() { + // 使用本地会话管理器获取当前服务器的在线用户登录名 + return localSessionManager.getLocalOnlineLoginNames(); + } + + /** + * 更新在线状态 - 通知所有用户在线列表变化 + */ + public void updateOnlineStatus() { + try { + // 创建在线状态消息 + SendVO onlineStatusMsg = new SendVO(); + onlineStatusMsg.setType("online_status"); + onlineStatusMsg.setSendmethod("broadcast"); + + // 获取在线用户列表 + List onlineUsers = getOnlineLoginNames(); + List onlineUserIds = getOnlineLoginUserId(); + + Map data = new HashMap<>(); + data.put("onlineUsers", onlineUsers); + data.put("onlineUserIds", onlineUserIds); + data.put("timestamp", System.currentTimeMillis()); + + onlineStatusMsg.setMsg(data); + + // 广播在线状态更新(只广播到当前服务器,避免循环广播) + broadcastLocalOnlineStatus(onlineStatusMsg); + + logger.info("在线状态更新: {} 个用户在线", onlineUsers.size()); + } catch (Exception e) { + logger.error("更新在线状态失败: " + e.getMessage(), e); + } + } + + /** + * 广播在线状态到本地用户 + */ + private void broadcastLocalOnlineStatus(SendVO message) { + logger.info("localSessionManager: {}", localSessionManager); + logger.info("localSessionManager.userSessions: {}", localSessionManager.getUserSessions()); + logger.info("localSessionManager.userSessions.values: {}", localSessionManager.getUserSessions().values()); + if (localSessionManager == null || localSessionManager.getUserSessions().isEmpty()) { + logger.error("localSessionManager is null, cannot broadcast online status"); + return; + } + + // 获取本地所有用户会话 + for (List sessions : localSessionManager.getUserSessions().values()) { + for (WebSocketSession session : sessions) { + if (session!=null&&session.isOpen()) { + try { + session.sendMessage(new TextMessage(message.toString())); + } catch (IOException e) { + logger.error("发送在线状态消息失败: " + e.getMessage(), e); + } } - } catch (IOException e) { - logger.error("给所有在线用户发送信息失败!" + e.getMessage(), e); } } } /** - * 给某个用户发送消息 - * - * @param loginName - * @param message + * 给所有在线用户发送消息 */ - public boolean sendMessageToUser(String loginName, SendVO message) { - boolean result = false; + public void sendMessageToAllUsers(SendVO message) { + // 获取所有在线用户ID + List onlineUserIds = getOnlineLoginUserId(); - //不能这样操作。 - //for (WebSocketSession user : users) { - List lst = userSession.get(message.getToid()); - - if (CollUtil.isNotEmpty(lst)) { - for (WebSocketSession user : lst) { - //if (user.getAttributes().get(Constants.WEBSOCKET_LOGINNAME).equals(loginName)) {//允许用户多个浏览器登录,每个浏览器页面都会收到用户信息 - try { - if (user.isOpen()) { - user.sendMessage(new TextMessage(message.toString())); - result = true; - } - } catch (IOException e) { - logger.error("给用户发送信息失败!" + e.getMessage(), e); - } - - //break;//注释掉此处意味着遍历该用户打开的所有页面并发送信息,否则只会向用户登录的第一个网页发送信息。 - //} - } + for (Integer userId : onlineUserIds) { + String userIdStr = String.valueOf(userId); + distributedMessageService.sendToUser(userIdStr, message,localSessionManager.getUserSessions()); } - return result; + logger.debug("向 {} 个在线用户发送消息", onlineUserIds.size()); } - - public void updateOnlineStatus() { - //this.sendMessageToAllUsers(this.getOnlineLoginNames());//通知所有用户更新在线信息 - } - } \ No newline at end of file diff --git a/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java b/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java index dd4bb67d..3138043c 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java +++ b/mall-im/src/main/java/com/suisung/mall/im/controller/admin/ChatSocketInfoController.java @@ -45,8 +45,8 @@ public class ChatSocketInfoController { @RequestMapping(value = "/getUserOnline", method = RequestMethod.POST) public List getUserOnline(@RequestBody List user_ids) { logger.info(I18nUtil._("接收的用户ids:") + CollUtil.join(user_ids, ",")); - //List onlineLoginUserIds = distributedSessionService.getOnlineUserIds(); - List onlineLoginUserIds = new MallsuiteImSocketHandler().getOnlineLoginUserId(); + List onlineLoginUserIds = distributedSessionService.getOnlineUserIds(); + // List onlineLoginUserIds = new MallsuiteImSocketHandler().getOnlineLoginUserId(); Iterator online_user_ids_iter = onlineLoginUserIds.iterator(); // 处理移除非本店铺客服 while (online_user_ids_iter.hasNext()) { From 023bd790dfdd2d47227276985be2ba541dc3f536 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 19 Nov 2025 16:56:51 +0800 Subject: [PATCH 07/81] =?UTF-8?q?=E5=BA=97=E9=93=BA=E5=BC=80=E4=B8=9A?= =?UTF-8?q?=E7=AD=B9=E5=A4=87=E7=8A=B6=E6=80=81=E5=88=B0=E6=9C=9F=E8=BD=AC?= =?UTF-8?q?=E6=AD=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ShopActivityCutpriceServiceImpl.java | 234 ++++++++++-------- .../quartz/job/StoreValidTimeJod.java | 3 + .../store/service/ShopStoreBaseService.java | 9 + .../service/impl/ShopMchEntryServiceImpl.java | 15 +- .../impl/ShopStoreBaseServiceImpl.java | 23 ++ 5 files changed, 172 insertions(+), 112 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java index ba64148c..9b9ec778 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java @@ -330,13 +330,11 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl 0 && cut_num >= num) { - return CommonResult.failed(I18nUtil._("今日帮砍次数已用完!")); + if (maxCuts > 0 && usedCuts >= maxCuts) { + return CommonResult.failed(I18nUtil._("今日帮砍次数已达上限!")); + } + } + } catch (Exception e) { + // Redis检查失败时继续执行砍价操作 } } - BigDecimal ac_sale_price = shopActivityCutprice.getAc_sale_price(); - BigDecimal ac_mix_limit_price = shopActivityCutprice.getAc_mix_limit_price(); + BigDecimal salePrice = cutprice.getAc_sale_price(); + BigDecimal minPrice = cutprice.getAc_mix_limit_price(); - // 检查价格数据是否完整 - if (ac_sale_price == null || ac_mix_limit_price == null) { - return CommonResult.failed(I18nUtil._("价格数据异常!")); + // 检查价格数据完整性 + if (salePrice == null || minPrice == null) { + return CommonResult.failed(I18nUtil._("商品价格数据异常!")); } // 检查是否已达到最低价 - if (NumberUtil.isLessOrEqual(ac_sale_price, ac_mix_limit_price)) { - // 根据上次的状态,立即更改状态:6-砍价助力已完成待下单; - updateCutPriceState(shopActivityCutprice.getAc_id(), null, CommonConstant.CutPrice_Order_State_CutFinished); - - return CommonResult.failed(I18nUtil._("已达到最低价!")); + if (NumberUtil.isLessOrEqual(salePrice, minPrice)) { + updateCutPriceState(cutprice.getAc_id(), null, CommonConstant.CutPrice_Order_State_CutFinished); + return CommonResult.failed(I18nUtil._("已砍到最低价啦!")); } - // 检查是否已经帮过好友砍了价 - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("user_id", user_id).eq("ac_id", ac_id); - long ach_num = shopActivityCutpriceHistoryService.count(queryWrapper); - if (ach_num > 0) { - return CommonResult.failed(I18nUtil._("已经帮好友砍过价!")); + // 检查是否已经帮过好友砍价 + try { + if (shopActivityCutpriceHistoryService == null) { + return CommonResult.failed(I18nUtil._("系统繁忙,请稍后再试!")); + } + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id", user_id).eq("ac_id", ac_id); + if (shopActivityCutpriceHistoryService.count(queryWrapper) > 0) { + return CommonResult.failed(I18nUtil._("您已经帮好友砍过价了!")); + } + } catch (Exception e) { + return CommonResult.failed(I18nUtil._("系统繁忙,请稍后再试!")); } // 计算砍价金额 - BigDecimal cut_price = shopStoreActivityBaseService.getCutDownPrice(shopStoreActivityBase, shopActivityCutprice); - if (cut_price == null || cut_price.compareTo(BigDecimal.ZERO) <= 0) { - return CommonResult.failed(I18nUtil._("砍价失败!")); + BigDecimal cutPrice; + try { + cutPrice = shopStoreActivityBaseService.getCutDownPrice(activityBase, cutprice); + if (cutPrice == null || cutPrice.compareTo(BigDecimal.ZERO) <= 0) { + return CommonResult.failed(I18nUtil._("砍价失败,请重试!")); + } + } catch (Exception e) { + return CommonResult.failed(I18nUtil._("砍价失败,请重试!")); } // 获取商品ID - String str_activity_rule = shopStoreActivityBase.getActivity_rule(); - if (StrUtil.isBlank(str_activity_rule)) { + String ruleStr = activityBase.getActivity_rule(); + if (StrUtil.isBlank(ruleStr)) { return CommonResult.failed(I18nUtil._("活动规则数据异常!")); } - JSONObject activity_rule = JSONUtil.parseObj(str_activity_rule); - Long item_id = activity_rule.get("item_id", Long.class); - if (item_id == null) { - return CommonResult.failed(I18nUtil._("未找到商品信息!")); + try { + JSONObject activityRule = JSONUtil.parseObj(ruleStr); + Long itemId = activityRule.get("item_id", Long.class); + if (itemId == null) { + return CommonResult.failed(I18nUtil._("未找到对应商品!")); + } + + // 创建砍价历史记录 + ShopActivityCutpriceHistory history = new ShopActivityCutpriceHistory(); + history.setActivity_id(cutprice.getActivity_id()); + history.setUser_id(user_id); + history.setAch_price(cutPrice); + history.setItem_id(itemId); + history.setAch_datetime(new Date()); + history.setAc_id(ac_id); + + // 保存历史记录 + if (!shopActivityCutpriceHistoryService.saveOrUpdate(history)) { + throw new ApiException(I18nUtil._("保存砍价记录失败!")); + } + + // 更新砍价信息 + cutprice.setAc_sale_price(NumberUtil.sub(salePrice, cutPrice)); + cutprice.setAc_num(cutprice.getAc_num() + 1); + if (!edit(cutprice)) { + throw new ApiException(I18nUtil._("更新砍价信息失败!")); + } + + // 更新帮砍次数 + if (!cutprice.getUser_id().equals(user_id) && redisService != null) { + try { + DateTime today = DateUtil.beginOfDay(new Date()); + Integer cutNum = Convert.toInt(redisService.hGet("cutprice-" + today, user_id.toString()), 0); + redisService.hSet("cutprice-" + today, user_id.toString(), cutNum + 1, 24 * 60 * 60 * 1000); + } catch (Exception e) { + // Redis更新失败不影响主流程 + } + } + + // 如果已达到最低价,更新状态 + if (NumberUtil.isLessOrEqual(cutprice.getAc_sale_price(), minPrice)) { + updateCutPriceState(cutprice.getAc_id(), null, CommonConstant.CutPrice_Order_State_CutFinished); + } + + return CommonResult.success(history); + } catch (ApiException e) { + throw e; + } catch (Exception e) { + throw new ApiException(I18nUtil._("砍价操作失败!")); } - - // 创建砍价历史记录 - ShopActivityCutpriceHistory ach_data = new ShopActivityCutpriceHistory(); - ach_data.setActivity_id(activity_id); - ach_data.setUser_id(user_id); - ach_data.setAch_price(cut_price); - ach_data.setItem_id(item_id); - ach_data.setAch_datetime(new Date()); - ach_data.setAc_id(ac_id); - - // 保存砍价历史记录 - if (!shopActivityCutpriceHistoryService.saveOrUpdate(ach_data)) { - throw new ApiException(I18nUtil._("保存砍价历史失败!")); - } - - // 更新砍价信息 - shopActivityCutprice.setAc_sale_price(NumberUtil.sub(ac_sale_price, cut_price)); - shopActivityCutprice.setAc_num(shopActivityCutprice.getAc_num() + 1); - if (!edit(shopActivityCutprice)) { - throw new ApiException(I18nUtil._("更新砍价信息失败!")); - } - - // 更新帮砍次数(如果不是自己砍自己的话) - if (!shopActivityCutprice.getUser_id().equals(user_id)) { - DateTime today = DateUtil.beginOfDay(new Date()); - Integer cut_num = Convert.toInt(redisService.hGet("cutprice-" + today, user_id.toString()), 0); - redisService.hSet("cutprice-" + today, user_id.toString(), cut_num + 1, 24 * 60 * 60 * 1000); - } - - // 根据最新砍价信息(最后一次砍价成功之后,达到最低砍价价格),更新砍价订单状态 - if (NumberUtil.isGreaterOrEqual(shopActivityCutprice.getAc_sale_price(), ac_mix_limit_price)) { - updateCutPriceState(shopActivityCutprice.getAc_id(), null, CommonConstant.CutPrice_Order_State_CutFinished); - } - - return CommonResult.success(ach_data); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/StoreValidTimeJod.java b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/StoreValidTimeJod.java index c1789a87..12cb0120 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/StoreValidTimeJod.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/StoreValidTimeJod.java @@ -65,6 +65,9 @@ public class StoreValidTimeJod extends QuartzJobBean { } page++; } + + // 准备筹备中的店铺,到期转正常营业 + storeBaseService.batchUpdateStoreBizStateToOpening(); } } \ No newline at end of file diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java index b00c7986..a24f75e2 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java @@ -255,6 +255,15 @@ public interface ShopStoreBaseService extends IBaseService { */ Date getLatestBizOpeningDate(String storeIds); + + /** + * 批量更新店铺营业状态为营业中 + * 将符合条件的"筹备中"状态店铺更新为"营业中"状态 + * + * @return Boolean 更新是否成功 + */ + Boolean batchUpdateStoreBizStateToOpening(); + // Page getMobileStoreList(Integer page, Integer rows); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java index cddf2a7d..0f5a945f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java @@ -339,9 +339,10 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl tmplArgs = new HashMap<>(1); tmplArgs.put("name", record.getStore_name()); // 商家店铺名 - // 【桂平发发网络】通知管理员有商家申请入驻 - if (!shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_498535058", tmplArgs)) { - shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs); // 【小发同城】通知管理员有商家申请入驻 + // 【小发同城】通知管理员有商家申请入驻 + if (!shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs)) { + // 【桂平发发网络】通知管理员有商家申请入驻 + shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_498535058", tmplArgs); } } @@ -471,10 +472,10 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl tmplArgs = new HashMap<>(1); tmplArgs.put("name", mchName); // 商家公司名称 - // 【桂平发发网络】通知管理员有商家申请入驻 - if (!shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_498535058", tmplArgs)) { - // 尊敬的管理员,商家 ${name},提交了入驻我们平台的申请,请及时对相关资质材料予以审核,以便推进后续流程。 - shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs); // 【小发同城】通知管理员有商家申请入驻 + // 【小发同城】通知管理员有商家申请入驻:尊敬的管理员,商家 ${name},提交了入驻我们平台的申请,请及时对相关资质材料予以审核,以便推进后续流程。 + if (!shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs)) { + // 【桂平发发网络】通知管理员有商家申请入驻 + shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_498535058", tmplArgs); } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java index c0807867..dd0b8419 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java @@ -4404,6 +4404,29 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("store_biz_state", CommonConstant.Store_Biz_State_PreActivity) // 筹备中状态 + .eq("store_is_open", CommonConstant.Enable) // 店铺已开启 + .le("store_biz_opening_date", new Date()) // 开业日期小于等于当前日期 + .set("store_biz_state", CommonConstant.Store_Biz_State_Opening); // 更新为营业中状态 + + return update(updateWrapper); + } catch (Exception e) { + log.error("批量更新店铺营业状态失败", e); + // 发生异常时返回true,避免影响主流程执行 + return Boolean.TRUE; + } + } + // @Override // public Page getMobileStoreList(Integer page, Integer rows) { From 4ce40ede170b8f6daac3fa732baee0bc0a30ee9e Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 19 Nov 2025 16:59:00 +0800 Subject: [PATCH 08/81] =?UTF-8?q?im=E5=88=86=E5=B8=83=E5=BC=8F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=96=B9=E6=A1=88-=E5=8D=95=E6=9C=BA=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/service/DistributedMessageService.java | 8 ++++++-- .../im/common/websocket/service/LocalSessionManager.java | 4 ++++ .../service/onchat/MallsuiteImSocketHandler.java | 4 ++-- .../mall/sns/service/impl/SnsUserMessageServiceImpl.java | 4 ++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java index 74175b2f..f35bd27c 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java @@ -34,6 +34,10 @@ public class DistributedMessageService { /** * 发送消息给用户 + * @param targetUserId 目标用户就是account的id + * @param message + * @param userSessions + * @return */ public boolean sendToUser(String targetUserId, SendVO message, ConcurrentHashMap> userSessions) { log.info("targetUserId{},message:{}", targetUserId, message); @@ -46,10 +50,10 @@ public class DistributedMessageService { if (isCurrentServer(targetServer)) { // 用户在当前服务器,直接发送 - return localSessionManager.sendToUser(targetUserId, message,userSessions); + return localSessionManager.sendToUser(message.getToid(), message,userSessions); } else { // 用户在其他服务器,通过RabbitMQ转发 - forwardToUser(targetServer, targetUserId, message); + forwardToUser(targetServer, message.getToid(), message); return true; } } diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java index c9f845b6..e05e58b1 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java @@ -68,6 +68,10 @@ public class LocalSessionManager { /** * 发送消息给用户 + * @param userId session的id + * @param message + * @param userSession + * @return */ public boolean sendToUser(String userId, SendVO message,ConcurrentHashMap> userSession) { if (userId == null || message == null) { diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index e4b11f83..5efe29c2 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -130,7 +130,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { chat.setMsg(msg); chat.setType("friend"); chat.setCreate_date(new Date()); - boolean isSuccess = distributedMessageService.sendToUser(receiver, sendVO,localSessionManager.getUserSessions()); + boolean isSuccess = distributedMessageService.sendToUser(String.valueOf(toUserId), sendVO,localSessionManager.getUserSessions()); if (isSuccess) { chat.setStatus("1"); } else { @@ -140,7 +140,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { sendVO.setMsg_type("text"); sendVO.setMessage_length("0"); sendVO.setId(to.getId()); - distributedMessageService.sendToUser(sender, sendVO,localSessionManager.getUserSessions()); + distributedMessageService.sendToUser(String.valueOf(toUserId), sendVO,localSessionManager.getUserSessions()); chat.setStatus("0"); } chatHistoryService.saveNew(chat); diff --git a/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsUserMessageServiceImpl.java b/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsUserMessageServiceImpl.java index 48945ead..da462ab9 100644 --- a/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsUserMessageServiceImpl.java +++ b/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsUserMessageServiceImpl.java @@ -820,6 +820,10 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl Date: Wed, 19 Nov 2025 17:21:00 +0800 Subject: [PATCH 09/81] =?UTF-8?q?im=E5=88=86=E5=B8=83=E5=BC=8F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=96=B9=E6=A1=88-=E5=8D=95=E6=9C=BA=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/websocket/service/DistributedMessageService.java | 4 ++-- .../mall/im/common/websocket/service/LocalSessionManager.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java index f35bd27c..d6ba45ae 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java @@ -50,10 +50,10 @@ public class DistributedMessageService { if (isCurrentServer(targetServer)) { // 用户在当前服务器,直接发送 - return localSessionManager.sendToUser(message.getToid(), message,userSessions); + return localSessionManager.sendToUser(targetUserId, message,userSessions); } else { // 用户在其他服务器,通过RabbitMQ转发 - forwardToUser(targetServer, message.getToid(), message); + forwardToUser(targetServer, targetUserId, message); return true; } } diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java index e05e58b1..a3bb6776 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java @@ -68,7 +68,7 @@ public class LocalSessionManager { /** * 发送消息给用户 - * @param userId session的id + * @param userId account的id * @param message * @param userSession * @return From 1b97836bea96222565178eeabf3255cf7e27345e Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 19 Nov 2025 17:40:00 +0800 Subject: [PATCH 10/81] =?UTF-8?q?im=E5=88=86=E5=B8=83=E5=BC=8F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=96=B9=E6=A1=88-=E5=8D=95=E6=9C=BA=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/service/onchat/MallsuiteImSocketHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index 5efe29c2..0d238ce4 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -130,7 +130,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { chat.setMsg(msg); chat.setType("friend"); chat.setCreate_date(new Date()); - boolean isSuccess = distributedMessageService.sendToUser(String.valueOf(toUserId), sendVO,localSessionManager.getUserSessions()); + boolean isSuccess = distributedMessageService.sendToUser(String.valueOf(receiveDTO.getTo().getFriend_id()), sendVO,localSessionManager.getUserSessions()); if (isSuccess) { chat.setStatus("1"); } else { @@ -140,7 +140,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { sendVO.setMsg_type("text"); sendVO.setMessage_length("0"); sendVO.setId(to.getId()); - distributedMessageService.sendToUser(String.valueOf(toUserId), sendVO,localSessionManager.getUserSessions()); + distributedMessageService.sendToUser(String.valueOf(receiveDTO.getTo().getFriend_id()), sendVO,localSessionManager.getUserSessions()); chat.setStatus("0"); } chatHistoryService.saveNew(chat); From 3ca6dcbec9e198c74e19264c25d22520af7cad02 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 19 Nov 2025 23:21:37 +0800 Subject: [PATCH 11/81] =?UTF-8?q?=E7=A0=8D=E4=BB=B7=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=EF=BC=8C=E5=BA=93=E5=AD=98=E9=80=BB=E8=BE=91=E5=A4=84=E7=90=86?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ShopActivityCutpriceServiceImpl.java | 49 ++++++++++++++----- .../order/service/ShopOrderInfoService.java | 9 ++++ .../impl/ShopOrderInfoServiceImpl.java | 44 +++++++++++++++++ .../service/ShopStoreActivityBaseService.java | 10 ++++ .../ShopStoreActivityBaseServiceImpl.java | 40 +++++++++++++++ 5 files changed, 141 insertions(+), 11 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java index 9b9ec778..4b4913ed 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java @@ -34,6 +34,7 @@ import com.suisung.mall.shop.activity.service.ShopActivityCutpriceService; import com.suisung.mall.shop.activity.service.ShopActivityGroupbookingHistoryService; import com.suisung.mall.shop.activity.service.ShopActivityGroupbookingService; import com.suisung.mall.shop.base.service.AccountBaseConfigService; +import com.suisung.mall.shop.order.service.ShopOrderInfoService; import com.suisung.mall.shop.store.service.ShopStoreActivityBaseService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -74,6 +75,10 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl check_result = checkCutPriceExpiredAndStock(activityBase); if (!check_result.getFirst()) { + // 库存不够,立即更改活动状态为已结束 + shopStoreActivityBaseService.updateActivityState(activity_id, StateCode.ACTIVITY_STATE_FINISHED); throw new ApiException(check_result.getSecond()); } @@ -441,6 +449,15 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl check_result = checkCutPriceExpiredAndStock(activityBase); + if (!check_result.getFirst()) { + // 库存不够,立即更改活动状态为已结束 + shopStoreActivityBaseService.updateActivityState(cutprice.getActivity_id(), StateCode.ACTIVITY_STATE_FINISHED); + throw new ApiException(check_result.getSecond()); + } + } catch (Exception e) { return CommonResult.failed(I18nUtil._("系统繁忙,请稍后再试!")); } @@ -651,6 +668,16 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("activity_id", shopStoreActivityBase.getActivity_id()) - .in("state", Arrays.asList( - CommonConstant.CutPrice_Order_State_Finished, - CommonConstant.CutPrice_Order_State_CutFinished, - CommonConstant.CutPrice_Order_State_ING - )); - long recordCount = count(queryWrapper); +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("activity_id", shopStoreActivityBase.getActivity_id()) +// .isNotNull("order_id").likeRight("order_id", "DD_") +// .eq("state", CommonConstant.CutPrice_Order_State_Finished); +// long recordCount = count(queryWrapper); + + // 实时查询活动的订单数量 + long recordCount = shopOrderInfoService.fetchActivityOrderSuccessCount(Convert.toStr(shopStoreActivityBase.getActivity_id()), Convert.toStr(StateCode.ACTIVITY_TYPE_CUTPRICE)); // 判断库存是否充足(当已占用库存大于等于总库存时,表示库存不足) if (recordCount >= productCount) { - return Pair.of(false, I18nUtil._("活动商品库存不足,请稍后再来。")); + return Pair.of(false, I18nUtil._("活动商品库存不足,请稍后再参与!")); } // 所有检查通过 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java index b0027f30..968209fd 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java @@ -143,4 +143,13 @@ public interface ShopOrderInfoService extends IBaseService { * @return */ List genBookingOrderArgList(String storeId); + + /** + * 获取某个活动订单成功数量 + * + * @param activityId 活动ID + * @param activityTypeId 活动类型ID, 可选参数 + * @return + */ + long fetchActivityOrderSuccessCount(String activityId, String activityTypeId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java index 46dc2bb2..b0b770f7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java @@ -7,6 +7,7 @@ import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.suisung.mall.common.api.CommonResult; @@ -1231,6 +1232,49 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopOrderInfo::getActivity_id, activityId); + + // 如果activityTypeId不为空,则添加条件 + if (StrUtil.isNotBlank(activityTypeId)) { + queryWrapper.eq(ShopOrderInfo::getActivity_type_id, activityTypeId); + } + + // 添加订单状态条件 + List successOrderStates = Arrays.asList( + StateCode.ORDER_STATE_WAIT_PAID, + StateCode.ORDER_STATE_PICKING, + StateCode.ORDER_STATE_WAIT_SHIPPING, + StateCode.ORDER_STATE_SHIPPED, + StateCode.ORDER_STATE_RECEIVED, + StateCode.ORDER_STATE_FINISH); + + queryWrapper.in(ShopOrderInfo::getOrder_state_id, successOrderStates); + + try { + return count(queryWrapper); + } catch (Exception e) { + logger.error("获取活动订单出错, activityId: {}, activityTypeId: {}", + activityId, activityTypeId, e); + return 0L; + } + } + /** * 根据一个或多个店铺id获取有效店铺的有效营业时间段 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreActivityBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreActivityBaseService.java index c457c7fe..a4e13842 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreActivityBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreActivityBaseService.java @@ -199,4 +199,14 @@ public interface ShopStoreActivityBaseService extends IBaseService Date: Thu, 20 Nov 2025 00:10:07 +0800 Subject: [PATCH 12/81] =?UTF-8?q?=E7=A0=8D=E4=BB=B7=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=EF=BC=8C=E4=B8=8B=E5=8D=95=E5=89=8D=E6=A3=80=E6=9F=A5=20?= =?UTF-8?q?=E5=BA=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ShopActivityCutpriceServiceImpl.java | 37 ++++++----- .../impl/ShopOrderBaseServiceImpl.java | 11 ++-- .../service/ShopStoreActivityBaseService.java | 7 ++ .../ShopStoreActivityBaseServiceImpl.java | 64 +++++++++++++++++++ 4 files changed, 99 insertions(+), 20 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java index 4b4913ed..ebf700c7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java @@ -305,17 +305,19 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl checkStockResult = checkCutPriceExpiredAndStock(activityBase); + // 立即参与活动? boolean is_join_activity = false; // 如果用户未参与该砍价活动,则创建新的砍价记录 if (cutprice_row == null) { - // 需要检查活动有效期和活动商品库存是否足够 - Pair check_result = checkCutPriceExpiredAndStock(activityBase); - if (!check_result.getFirst()) { + + if (!checkStockResult.getFirst()) { // 库存不够,立即更改活动状态为已结束 shopStoreActivityBaseService.updateActivityState(activity_id, StateCode.ACTIVITY_STATE_FINISHED); - throw new ApiException(check_result.getSecond()); + throw new ApiException(checkStockResult.getSecond()); } cutprice_row = new ShopActivityCutprice(); @@ -375,19 +377,24 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(acId, userId); @@ -1673,10 +1678,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl= productCount; + if (isSoldOut) { + logger.info("活动商品已售完:activity_id={}, 已售数量={}, 库存数量={}", + activity_id, soldCount, productCount); + } + + return isSoldOut; + } catch (Exception e) { + logger.error("活动商品售完检查异常:activity_id={}", activity_id, e); + return true; // 出现异常时保守地返回已售完 + } + } + @Transactional public boolean removeActivityBase(Integer activity_id, ShopStoreActivityBase activity_row) { From ac3b9216d80f6691c10f94e9bc4141de8ab32d06 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Thu, 20 Nov 2025 00:18:18 +0800 Subject: [PATCH 13/81] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=A2=84=E7=BA=A6?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=97=A0=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ShopOrderBaseServiceImpl.java | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index b8153e8c..144bb79e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -1580,25 +1580,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(acId, userId); - if (!canDoOrderCutPriceActivity.getFirst()) { - logger.error(canDoOrderCutPriceActivity.getSecond()); - throw new ApiException(I18nUtil._("砍价活动未达标,请继续努力,再提交订单。")); - } - } // 注:(重要)邮费检测和计算 dealWithCalFee(calFreight, cartData, chainId, isEdu); @@ -1626,22 +1607,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl pair = shopOrderInfoService.checkBookingOrderArgs(checkedStore, bookingState, bookingBeginTime, bookingEndTime); -// if (!pair.getFirst()) { -// throw new ApiException(I18nUtil._(pair.getSecond())); -// } -// -// cartData.put("booking_state", bookingState); -// cartData.put("booking_begin_time", bookingBeginTime); -// cartData.put("booking_end_time", bookingEndTime); -// cartData.put("booking_at", bookingAt); -// } // 添加保存订单(关键方法) List orderIdRow = addOrder(cartData, true, false, null); @@ -1667,6 +1632,26 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(acId, userId); + if (!canDoOrderCutPriceActivity.getFirst()) { + logger.error(canDoOrderCutPriceActivity.getSecond()); + throw new ApiException(I18nUtil._("砍价活动未达标,请继续努力,再提交订单。")); + } + } + // 判断是否拼团购买 if (gbId != null) { QueryWrapper historyQueryWrapper = new QueryWrapper<>(); From c8699f0bf2cf00fc6191999f61f67df1519ab16c Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 09:09:14 +0800 Subject: [PATCH 14/81] =?UTF-8?q?im=E5=88=86=E5=B8=83=E5=BC=8F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=96=B9=E6=A1=88-=E5=8D=95=E6=9C=BA=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/LocalSessionManager.java | 25 ++------------- .../onchat/MallsuiteImSocketHandler.java | 32 +++++++++++++++++-- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java index a3bb6776..98a83d13 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java @@ -1,4 +1,5 @@ package com.suisung.mall.im.common.websocket.service; +import com.suisung.mall.im.common.websocket.service.onchat.MallsuiteImSocketHandler; import com.suisung.mall.im.pojo.vo.SendVO; import lombok.Getter; import lombok.Setter; @@ -28,28 +29,8 @@ public class LocalSessionManager { // 本地存储的群组会话 (groupId -> sessions) private ConcurrentHashMap> groupSessions = new ConcurrentHashMap<>(); - - - /** - * 添加用户会话 - */ - public void addUserSession(String userId, WebSocketSession session) { - if (userId == null || session == null) { - log.info("添加用户会话失败: 参数为空"); - return; - } - userSessions.compute(userId, (key, existingSessions) -> { - if (existingSessions == null) { - existingSessions = new CopyOnWriteArrayList<>(); - } -// if (!existingSessions.contains(session)) { -// existingSessions.add(session); -// } - existingSessions.add(session); - return existingSessions; - }); - - log.info("添加用户会话成功: userId={}, sessionId={}", userId, session.getId()); + public LocalSessionManager() { + this.userSessions = MallsuiteImSocketHandler.userSessions; } /** diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index 0d238ce4..2a3d5223 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -22,6 +22,7 @@ import org.springframework.web.socket.*; import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; public class MallsuiteImSocketHandler implements WebSocketHandler { @@ -33,6 +34,8 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { // private static Map> userSession; // private static Map> groupSession; + public static ConcurrentHashMap> userSessions; + @Autowired private DistributedSessionService distributedSessionService; @@ -45,6 +48,9 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { @Autowired private ChatHistoryService chatHistoryService; + static { + userSessions=new ConcurrentHashMap<>(); + } //用户上线后触发 @Override @@ -55,9 +61,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { String sessionId = session.getId(); // 存储到本地会话管理 - ConcurrentHashMap> userSessions=new ConcurrentHashMap<>(); - localSessionManager.setUserSessions(userSessions); - localSessionManager.addUserSession(loginUserId, session); + this.addUserSession(loginUserId, session); logger.info("添加会话到本地成功:{}", localSessionManager.getUserSessions().values()); @@ -334,4 +338,26 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { logger.debug("向 {} 个在线用户发送消息", onlineUserIds.size()); } + + /** + * 添加用户会话 + */ + public void addUserSession(String userId, WebSocketSession session) { + if (userId == null || session == null) { + logger.info("添加用户会话失败: 参数为空"); + return; + } + userSessions.compute(userId, (key, existingSessions) -> { + if (existingSessions == null) { + existingSessions = new CopyOnWriteArrayList<>(); + } +// if (!existingSessions.contains(session)) { +// existingSessions.add(session); +// } + existingSessions.add(session); + return existingSessions; + }); + + logger.info("添加用户会话成功: userId={}, sessionId={}", userId, session.getId()); + } } \ No newline at end of file From 0b6c87aa311e64d43b5b394cc1792df50c14e9e8 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 09:36:21 +0800 Subject: [PATCH 15/81] =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E4=B8=AA=E8=A7=84=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ShopProductBaseServiceImpl.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java index 2fc346e5..655d46af 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java @@ -2076,6 +2076,20 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl 0){ + JSONObject jsonObject= (JSONObject) jsonArray_spec.get(0); + JSONArray jsonArray_item= (JSONArray) jsonObject.get("item"); + if(jsonArray_item.size() > 0){ + JSONObject jsonObjectItem= (JSONObject) jsonArray_item.get(0); + String itemSpec= (String) jsonObjectItem.get("name"); + String product_name=product_base_row.get("product_name")+itemSpec; + product_base_row.put("product_name",product_name); + } + } + } + Integer product_sale_num = Convert.toInt(product_index_row.get("product_sale_num")); // if (product_base_row != null) { From 47331a5b2af483973bcffd2c1b76337e3ac40572 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 10:35:14 +0800 Subject: [PATCH 16/81] =?UTF-8?q?im=E8=B0=83=E6=95=B4=E7=BB=84=E7=9A=84ses?= =?UTF-8?q?ion,=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/DistributedMessageService.java | 5 ++--- .../service/LocalSessionManager.java | 19 ++++------------ .../service/MessageConsumerService.java | 5 ++--- .../onchat/MallsuiteImSocketHandler.java | 22 ++++++++++++++----- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java index d6ba45ae..0a317f5b 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/DistributedMessageService.java @@ -36,10 +36,9 @@ public class DistributedMessageService { * 发送消息给用户 * @param targetUserId 目标用户就是account的id * @param message - * @param userSessions * @return */ - public boolean sendToUser(String targetUserId, SendVO message, ConcurrentHashMap> userSessions) { + public boolean sendToUser(String targetUserId, SendVO message) { log.info("targetUserId{},message:{}", targetUserId, message); String targetServer = sessionService.getUserServer(targetUserId); @@ -50,7 +49,7 @@ public class DistributedMessageService { if (isCurrentServer(targetServer)) { // 用户在当前服务器,直接发送 - return localSessionManager.sendToUser(targetUserId, message,userSessions); + return localSessionManager.sendToUser(targetUserId, message); } else { // 用户在其他服务器,通过RabbitMQ转发 forwardToUser(targetServer, targetUserId, message); diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java index 98a83d13..72c3feeb 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java @@ -27,10 +27,11 @@ public class LocalSessionManager { private ConcurrentHashMap> userSessions; // 本地存储的群组会话 (groupId -> sessions) - private ConcurrentHashMap> groupSessions = new ConcurrentHashMap<>(); + private ConcurrentHashMap> groupSessions; public LocalSessionManager() { this.userSessions = MallsuiteImSocketHandler.userSessions; + this.groupSessions = MallsuiteImSocketHandler.groupSessions; } /** @@ -51,18 +52,14 @@ public class LocalSessionManager { * 发送消息给用户 * @param userId account的id * @param message - * @param userSession * @return */ - public boolean sendToUser(String userId, SendVO message,ConcurrentHashMap> userSession) { + public boolean sendToUser(String userId, SendVO message) { if (userId == null || message == null) { log.info("发送消息失败: 参数为空"); return false; } - if(null!=userSession){ - this.userSessions=userSession; - } - log.info("userSessions={}", userSession); + log.info("userSessions={}", userSessions); List sessions = userSessions.get(userId); if (sessions == null || sessions.isEmpty()) { log.info("用户没有活跃会话: {}", userId); @@ -111,14 +108,6 @@ public class LocalSessionManager { return false; } - /** - * 添加群组会话 - */ - public void addGroupSession(String groupId, WebSocketSession session) { - groupSessions.computeIfAbsent(groupId, k -> new CopyOnWriteArrayList<>()) - .add(session); - } - /** * 移除群组会话 */ diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java index 155ada80..ffb0d413 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/MessageConsumerService.java @@ -26,8 +26,7 @@ public class MessageConsumerService { public void consumeForwardMessage(Map message) { try { String type = (String) message.get("type"); - System.out.println("收到RabbitMQ消息, 类型: " + type + ", 服务器: " + rabbitMQManager.getServerId()); - + logger.info("收到RabbitMQ消息, 类型: {}, 服务器: {}", type, rabbitMQManager.getServerId()); switch (type) { case "SEND_TO_USER": handleSendToUser(message); @@ -65,7 +64,7 @@ public class MessageConsumerService { } if (userMsg != null) { - boolean success = localSessionManager.sendToUser(userId, userMsg,null); + boolean success = localSessionManager.sendToUser(userId, userMsg); logger.info("发送消息给用户 {}: {}", userId, success ? "成功" : "失败"); } else { logger.info("消息格式错误,无法发送给用户: {}", userId); diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index 2a3d5223..06ca3b13 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -36,6 +36,8 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { public static ConcurrentHashMap> userSessions; + public static ConcurrentHashMap> groupSessions; + @Autowired private DistributedSessionService distributedSessionService; @@ -50,6 +52,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { static { userSessions=new ConcurrentHashMap<>(); + groupSessions=new ConcurrentHashMap<>(); } //用户上线后触发 @@ -134,7 +137,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { chat.setMsg(msg); chat.setType("friend"); chat.setCreate_date(new Date()); - boolean isSuccess = distributedMessageService.sendToUser(String.valueOf(receiveDTO.getTo().getFriend_id()), sendVO,localSessionManager.getUserSessions()); + boolean isSuccess = distributedMessageService.sendToUser(String.valueOf(receiveDTO.getTo().getFriend_id()), sendVO); if (isSuccess) { chat.setStatus("1"); } else { @@ -144,7 +147,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { sendVO.setMsg_type("text"); sendVO.setMessage_length("0"); sendVO.setId(to.getId()); - distributedMessageService.sendToUser(String.valueOf(receiveDTO.getTo().getFriend_id()), sendVO,localSessionManager.getUserSessions()); + distributedMessageService.sendToUser(String.valueOf(receiveDTO.getTo().getFriend_id()), sendVO); chat.setStatus("0"); } chatHistoryService.saveNew(chat); @@ -160,7 +163,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { session.getAttributes().put(Constants.WEBSOCKET_GROUP_KEY, zid); // 添加到本地群组 - localSessionManager.addGroupSession(zid, session); + this.addGroupSession(zid, session); // 添加到分布式群组 String userId = (String) session.getAttributes().get(Constants.WEBSOCKET_LOGINNAME); @@ -233,7 +236,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { * 给某个用户发送消息 (兼容原有接口) */ public boolean sendMessageToUser(String loginName, SendVO message) { - return distributedMessageService.sendToUser(loginName, message,localSessionManager.getUserSessions()); + return distributedMessageService.sendToUser(loginName, message); } /** @@ -333,7 +336,7 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { for (Integer userId : onlineUserIds) { String userIdStr = String.valueOf(userId); - distributedMessageService.sendToUser(userIdStr, message,localSessionManager.getUserSessions()); + distributedMessageService.sendToUser(userIdStr, message); } logger.debug("向 {} 个在线用户发送消息", onlineUserIds.size()); @@ -360,4 +363,13 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { logger.info("添加用户会话成功: userId={}, sessionId={}", userId, session.getId()); } + + + /** + * 添加群组会话 + */ + public void addGroupSession(String groupId, WebSocketSession session) { + groupSessions.computeIfAbsent(groupId, k -> new CopyOnWriteArrayList<>()) + .add(session); + } } \ No newline at end of file From 3971c5f504a65cf4a8271290386d29e62c0142f0 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 11:34:33 +0800 Subject: [PATCH 17/81] =?UTF-8?q?im=E8=B0=83=E6=95=B4sesion,=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=B8=80=E6=AC=A1=E6=80=A7=E6=B8=85=E9=99=A4session?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/service/LocalSessionManager.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java index 72c3feeb..4e8ff23b 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/LocalSessionManager.java @@ -41,9 +41,9 @@ public class LocalSessionManager { if (userId == null || session == null) { return; } - userSessions.computeIfPresent(userId, (key, sessions) -> { - sessions.remove(session); + sessions.removeIf(webSocketSession -> + webSocketSession.getId().equals(session.getId())); return sessions.isEmpty() ? null : sessions; }); } @@ -112,13 +112,11 @@ public class LocalSessionManager { * 移除群组会话 */ public void removeGroupSession(String groupId, WebSocketSession session) { - List sessions = groupSessions.get(groupId); - if (sessions != null) { - sessions.remove(session); - if (sessions.isEmpty()) { - groupSessions.remove(groupId); - } - } + groupSessions.computeIfPresent(groupId, (key, gropSession) -> { + gropSession.removeIf(webSocketSession -> + webSocketSession.getId().equals(session.getId())); + return gropSession.isEmpty() ? null : gropSession; + }); } /** From 8eeee63f58915ad1a81efc78667d6fb872bf41a6 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 11:55:31 +0800 Subject: [PATCH 18/81] =?UTF-8?q?im=E8=B0=83=E6=95=B4sesion,=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=B8=80=E6=AC=A1=E6=80=A7=E6=B8=85=E9=99=A4redis?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/onchat/MallsuiteImSocketHandler.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index 06ca3b13..e2621931 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -219,8 +219,12 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { } // 从分布式存储注销 - distributedSessionService.unregisterUserSession(loginUserId, sessionId); - if (groupId != null) { + List sessions= userSessions.get(loginUserId); + if(null==sessions || sessions.isEmpty()){ + distributedSessionService.unregisterUserSession(loginUserId, sessionId); + } + List groupSessionList= groupSessions.get(groupId); + if (null==groupSessionList||groupSessionList.isEmpty()) { distributedSessionService.removeUserFromGroup(groupId, sessionId); } From 9d59fbcc9cc68a025ad1dbd4624e0e86bf77aafa Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 14:38:47 +0800 Subject: [PATCH 19/81] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E5=95=86=E5=93=81=E6=97=B6=EF=BC=8C=E8=BF=87=E6=BB=A4=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E6=B4=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/service/impl/ShopStoreActivityBaseServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreActivityBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreActivityBaseServiceImpl.java index a3855427..d50f8266 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreActivityBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreActivityBaseServiceImpl.java @@ -5209,7 +5209,7 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl item_row = shopStoreActivityItemService.find(itemQueryWrapper); - List item_id_row = item_row.stream().map(s -> s.getItem_id()).distinct().collect(Collectors.toList()); + List item_id_row = item_row.stream().filter(s->s.getActivity_item_state().equals(StateCode.ACTIVITY_STATE_NORMAL)).map(s -> s.getItem_id()).distinct().collect(Collectors.toList()); List activity_id_row = item_row.stream().map(s -> s.getActivity_id()).distinct().collect(Collectors.toList()); List used_id_row = new ArrayList<>(); From 102246877800a43ac24124fd84dc60a6ab739e0a Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 15:06:41 +0800 Subject: [PATCH 20/81] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=88=B0=E6=80=9D=E8=BF=85=EF=BC=8C=E5=8F=96=E4=BB=B7=E6=A0=BC?= =?UTF-8?q?=E4=B8=BA=E6=9C=80=E7=BB=88=E4=BB=B7=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/order/service/impl/ShopOrderReturnServiceImpl.java | 2 +- .../shop/sfexpress/service/impl/SFExpressApiServiceImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index 47b7a73f..fcc400bc 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1637,7 +1637,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getItem_unit_price(); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_amount(); if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id()); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java index f4a4f1c4..a215590a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java @@ -1183,7 +1183,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - String mapKey=item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getItem_unit_price(); + String mapKey=item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getOrder_item_amount(); if(StringUtils.isNotEmpty(saleTimeStr)){ mapKey=mapKey+"-"+saleTimeStr; } @@ -1356,7 +1356,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getItem_unit_price()+"-"+shopOrderBase.getOrder_time().getTime(); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getOrder_item_amount()+"-"+shopOrderBase.getOrder_time().getTime(); stockDeltaMap.put(mapKey, -order_item_quantity); syncThirdDataService.incrProductStockToRedis(stockDeltaMap,null); } From 528c76a912f309241b961b3e3f675fcaf98a8606 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 20 Nov 2025 15:12:35 +0800 Subject: [PATCH 21/81] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=88=B0=E6=80=9D=E8=BF=85=EF=BC=8C=E5=8F=96=E4=BB=B7=E6=A0=BC?= =?UTF-8?q?=E4=B8=BA=E6=9C=80=E7=BB=88=E4=BB=B7=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/order/service/impl/ShopOrderReturnServiceImpl.java | 2 +- .../shop/sfexpress/service/impl/SFExpressApiServiceImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index fcc400bc..9f9c423c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1637,7 +1637,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_amount(); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id()); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java index a215590a..8604ef80 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java @@ -1183,7 +1183,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - String mapKey=item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getOrder_item_amount(); + String mapKey=item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getOrder_item_unit_price(); if(StringUtils.isNotEmpty(saleTimeStr)){ mapKey=mapKey+"-"+saleTimeStr; } @@ -1356,7 +1356,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getOrder_item_amount()+"-"+shopOrderBase.getOrder_time().getTime(); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getOrder_item_unit_price()+"-"+shopOrderBase.getOrder_time().getTime(); stockDeltaMap.put(mapKey, -order_item_quantity); syncThirdDataService.incrProductStockToRedis(stockDeltaMap,null); } From db5bd06c35f0697beac57bf37dc74ad3e4c2053a Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Thu, 20 Nov 2025 22:13:40 +0800 Subject: [PATCH 22/81] =?UTF-8?q?=E7=A0=8D=E4=BB=B7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20=E8=A1=A5=E5=85=85=E5=92=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/utils/DateTimeUtils.java | 70 ++-- .../phone/DistributedLockHelperTest.java | 349 ++++++++++++++++++ .../service/ShopActivityCutpriceService.java | 4 +- .../impl/ShopActivityCutpriceServiceImpl.java | 13 +- .../quartz/job/UpdateActivityStatusJob.java | 67 +++- .../impl/ShopOrderBaseServiceImpl.java | 46 ++- .../service/ShopStoreActivityBaseService.java | 18 +- .../ShopStoreActivityBaseServiceImpl.java | 80 ++-- .../impl/ShopStoreBaseServiceImpl.java | 38 +- 9 files changed, 567 insertions(+), 118 deletions(-) create mode 100644 mall-common/src/test/com/suisung/mall/common/phone/DistributedLockHelperTest.java diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java index 6f559ab4..6b5dcf29 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java @@ -11,7 +11,6 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoField; -import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -492,7 +491,7 @@ public class DateTimeUtils { return -1; } } - + /** * 判断指定时间是否在两个时间点之间(包含边界) * @@ -602,6 +601,27 @@ public class DateTimeUtils { } } + public static boolean isActivityTimeValid(Date starTime, Date endTime, Date checkTime) { + log.debug("检查活动时间有效性 - 开始时间: {}, 结束时间: {}, 检查时间: {}", starTime, endTime, checkTime); + + if (starTime == null || endTime == null) { + log.error("活动时间验证失败 - 开始时间或结束时间为null. 开始时间: {}, 结束时间: {}", starTime, endTime); + return false; + } + + if (checkTime == null) { + checkTime = new Date(); + log.warn("检查时间为空,使用当前时间: {}", checkTime); + } + + boolean isValid = !checkTime.before(starTime) && !checkTime.after(endTime); + log.debug("活动时间验证结果: {} (检查时间>=开始时间, 检查时间<=结束时间)", + isValid); + + return isValid; + } + + public static void main(String[] args) { // System.out.println(convertLklDate("2021-02-19")); // 2025-01-02 // System.out.println(convertLklDate("2021-2-3")); // 2025-01-02 @@ -632,29 +652,29 @@ public class DateTimeUtils { // System.out.println("当前时间是否在工作时间内:" + isWorkTime); // System.out.println("多个时间段的交集结果:" + isNight); - - System.out.println("=== 测试 findTimeIntersection ==="); - - // 测试正常交集情况 - List> timeList1 = new ArrayList<>(); - timeList1.add(Pair.of("06:00", "17:00")); - timeList1.add(Pair.of("10:00", "18:00")); - - Pair intersection1 = findTimeInterSection(timeList1); - System.out.println("交集结果1: " + intersection1); // 应该是 10:00 - 17:00 - -// 测试无交集情况 - List> timeList2 = new ArrayList<>(); - timeList2.add(Pair.of("09:00", "12:00")); - timeList2.add(Pair.of("13:00", "17:00")); - - Pair intersection2 = findTimeInterSection(timeList2); - System.out.println("交集结果2: " + intersection2); // 应该是null - -// 测试空列表 - Pair intersection3 = findTimeInterSection(null); - System.out.println("交集结果3 (null输入): " + intersection3); // 应该是null - +// +// System.out.println("=== 测试 findTimeIntersection ==="); +// +// // 测试正常交集情况 +// List> timeList1 = new ArrayList<>(); +// timeList1.add(Pair.of("06:00", "17:00")); +// timeList1.add(Pair.of("10:00", "18:00")); +// +// Pair intersection1 = findTimeInterSection(timeList1); +// System.out.println("交集结果1: " + intersection1); // 应该是 10:00 - 17:00 +// +//// 测试无交集情况 +// List> timeList2 = new ArrayList<>(); +// timeList2.add(Pair.of("09:00", "12:00")); +// timeList2.add(Pair.of("13:00", "17:00")); +// +// Pair intersection2 = findTimeInterSection(timeList2); +// System.out.println("交集结果2: " + intersection2); // 应该是null +// +//// 测试空列表 +// Pair intersection3 = findTimeInterSection(null); +// System.out.println("交集结果3 (null输入): " + intersection3); // 应该是null +// } } \ No newline at end of file diff --git a/mall-common/src/test/com/suisung/mall/common/phone/DistributedLockHelperTest.java b/mall-common/src/test/com/suisung/mall/common/phone/DistributedLockHelperTest.java new file mode 100644 index 00000000..9fc90167 --- /dev/null +++ b/mall-common/src/test/com/suisung/mall/common/phone/DistributedLockHelperTest.java @@ -0,0 +1,349 @@ +package com.suisung.mall.common.utils; + +import com.suisung.mall.core.web.service.RedisService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * DistributedLockHelper综合测试套件 + */ +public class DistributedLockHelperTest { + + private DistributedLockHelper lockHelper; + + @Mock + private RedisService redisService; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + lockHelper = new DistributedLockHelper(); + ReflectionTestUtils.setField(lockHelper, "redisService", redisService); + System.out.println("=== 初始化测试环境 ==="); + } + + @Test + public void testTryLock_Success() { + System.out.println("开始执行: testTryLock_Success"); + + // 给定条件 + String lockKey = "test_lock"; + long expireTimeSec = 30L; + String expectedKey = "distributed_lock:" + lockKey; + System.out.println("测试参数 - 锁键: " + lockKey + ", 过期时间: " + expireTimeSec + "秒"); + + // 当调用时 + when(redisService.set(anyString(), anyString(), anyLong())).thenReturn(true); + boolean result = lockHelper.tryLock(lockKey, expireTimeSec); + System.out.println("获取锁结果: " + (result ? "成功" : "失败")); + + // 那么验证 + assertTrue(result, "锁应该成功获取"); + verify(redisService).set(eq(expectedKey), anyString(), eq(expireTimeSec)); + System.out.println("验证通过: Redis set 方法被正确调用"); + System.out.println("测试完成: testTryLock_Success\n"); + } + + @Test + public void testTryLock_Failure() { + System.out.println("开始执行: testTryLock_Failure"); + + // 给定条件 + String lockKey = "test_lock"; + long expireTimeSec = 30L; + System.out.println("测试参数 - 锁键: " + lockKey + ", 过期时间: " + expireTimeSec + "秒"); + + // 当调用时 + when(redisService.set(anyString(), anyString(), anyLong())).thenThrow(new RuntimeException("Redis错误")); + System.out.println("模拟Redis异常: Redis错误"); + + // 那么验证 + assertThrows(RuntimeException.class, () -> { + lockHelper.tryLock(lockKey, expireTimeSec); + }, "应该抛出RuntimeException"); + System.out.println("验证通过: 正确捕获了RuntimeException"); + System.out.println("测试完成: testTryLock_Failure\n"); + } + + @Test + public void testReleaseLock_Success() { + System.out.println("开始执行: testReleaseLock_Success"); + + // 给定条件 + String lockKey = "test_lock"; + String expectedKey = "distributed_lock:" + lockKey; + String lockValue = "uuid:1"; + System.out.println("测试参数 - 锁键: " + lockKey + ", 锁值: " + lockValue); + + // 设置线程本地变量 + ReflectionTestUtils.setField(lockHelper, "LOCK_VALUE_HOLDER", + new ThreadLocal() { + @Override + protected String initialValue() { + return lockValue; + } + }); + + when(redisService.get(expectedKey)).thenReturn(lockValue); + System.out.println("模拟Redis get返回值: " + lockValue); + + // 当调用时 + lockHelper.releaseLock(lockKey); + System.out.println("执行锁释放操作"); + + // 那么验证 + verify(redisService).del(expectedKey); + System.out.println("验证通过: Redis del 方法被正确调用"); + System.out.println("测试完成: testReleaseLock_Success\n"); + } + + @Test + public void testReleaseLock_WrongOwner() { + System.out.println("开始执行: testReleaseLock_WrongOwner"); + + // 给定条件 + String lockKey = "test_lock"; + String expectedKey = "distributed_lock:" + lockKey; + String currentValue = "uuid:1"; + String threadValue = "uuid:2"; // 不同的值 + System.out.println("测试参数 - 当前锁值: " + currentValue + ", 线程锁值: " + threadValue); + + // 设置线程本地变量 + ReflectionTestUtils.setField(lockHelper, "LOCK_VALUE_HOLDER", + new ThreadLocal() { + @Override + protected String initialValue() { + return threadValue; + } + }); + + when(redisService.get(expectedKey)).thenReturn(currentValue); + System.out.println("模拟Redis中当前锁值: " + currentValue); + + // 当调用时 + lockHelper.releaseLock(lockKey); + System.out.println("执行锁释放操作"); + + // 那么验证 + verify(redisService, never()).del(anyString()); + System.out.println("验证通过: Redis del 方法未被调用(防止误删)"); + System.out.println("测试完成: testReleaseLock_WrongOwner\n"); + } + + @Test + public void testConcurrentAccess_SingleLockAcquirer() throws InterruptedException { + System.out.println("开始执行: testConcurrentAccess_SingleLockAcquirer"); + + // 给定条件 + String lockKey = "concurrent_test_lock"; + int threadCount = 10; + ExecutorService executor = Executors.newFixedThreadPool(threadCount); + CountDownLatch latch = new CountDownLatch(threadCount); + AtomicInteger successCounter = new AtomicInteger(0); + System.out.println("测试参数 - 并发线程数: " + threadCount + ", 锁键: " + lockKey); + + // 模拟Redis并发访问行为 + when(redisService.set(anyString(), anyString(), anyLong())) + .thenAnswer(invocation -> { + // 只有第一次调用成功,其余都失败 + boolean result = successCounter.get() == 0; + if (result) { + System.out.println("线程[" + Thread.currentThread().getName() + "] 成功获取锁"); + } + return result; + }); + System.out.println("模拟Redis行为: 只允许一个线程获取锁"); + + // 当执行时 + for (int i = 0; i < threadCount; i++) { + final int threadId = i; + executor.submit(() -> { + try { + System.out.println("启动线程[" + threadId + "]"); + if (lockHelper.tryLock(lockKey, 30)) { + int count = successCounter.incrementAndGet(); + System.out.println("线程[" + threadId + "] 获取锁成功,当前成功计数: " + count); + lockHelper.releaseLock(lockKey); + System.out.println("线程[" + threadId + "] 释放锁"); + } else { + System.out.println("线程[" + threadId + "] 获取锁失败"); + } + } finally { + latch.countDown(); + System.out.println("线程[" + threadId + "] 执行完毕,剩余线程数: " + (latch.getCount())); + } + }); + } + + boolean completed = latch.await(5, TimeUnit.SECONDS); + executor.shutdown(); + System.out.println("所有线程执行完成: " + (completed ? "正常结束" : "超时结束")); + + // 那么验证 + int successCount = successCounter.get(); + assertEquals(1, successCount, "应该只有一个线程获得锁"); + System.out.println("验证通过: 实际成功获取锁的线程数为 " + successCount); + System.out.println("测试完成: testConcurrentAccess_SingleLockAcquirer\n"); + } + + @Test + public void testAutoRenewalFunctionality() throws InterruptedException { + System.out.println("开始执行: testAutoRenewalFunctionality"); + + // 给定条件 + String lockKey = "auto_renew_test_lock"; + long expireTimeSec = 5L; + long maxHoldTimeSec = 10L; + System.out.println("测试参数 - 锁键: " + lockKey + ", 过期时间: " + expireTimeSec + "秒, 最大持有时间: " + maxHoldTimeSec + "秒"); + + when(redisService.set(anyString(), anyString(), anyLong())).thenReturn(true); + when(redisService.get(anyString())).thenReturn("mock-value"); + System.out.println("模拟Redis set/get操作成功"); + + // 当调用时 + DistributedLockHelper.LockHolder lockHolder = + lockHelper.tryLockWithAutoRenew(lockKey, expireTimeSec, maxHoldTimeSec); + System.out.println("获取带自动续期功能的锁"); + + assertNotNull(lockHolder, "锁持有者不应为空"); + System.out.println("锁持有者创建成功"); + + // 等待可能的续期操作 + System.out.println("等待3秒观察自动续期行为..."); + Thread.sleep(3000); + + // 那么验证 + verify(redisService, atLeastOnce()).expire(anyString(), anyLong()); + System.out.println("验证通过: Redis expire 方法至少被调用一次"); + + // 清理 + lockHolder.close(); + System.out.println("关闭锁持有者,清理资源"); + System.out.println("测试完成: testAutoRenewalFunctionality\n"); + } + + @Test + public void testLockHolderAutoClose() { + System.out.println("开始执行: testLockHolderAutoClose"); + + // 给定条件 + String lockKey = "auto_close_test_lock"; + System.out.println("测试参数 - 锁键: " + lockKey); + + when(redisService.set(anyString(), anyString(), anyLong())).thenReturn(true); + when(redisService.get(anyString())).thenReturn("mock-value"); + System.out.println("模拟Redis操作成功"); + + // 当调用时 + System.out.println("使用try-with-resources语法获取锁"); + try (DistributedLockHelper.LockHolder holder = + lockHelper.tryLockWithAutoRenew(lockKey, 30, 300)) { + assertNotNull(holder, "锁持有者不应为空"); + System.out.println("锁持有者创建成功"); + } + System.out.println("try-with-resources块结束,自动调用close方法"); + + // 那么验证 + verify(redisService).del(anyString()); + System.out.println("验证通过: Redis del 方法被正确调用"); + System.out.println("测试完成: testLockHolderAutoClose\n"); + } + + @Test + public void testMultipleLocksIndependence() { + System.out.println("开始执行: testMultipleLocksIndependence"); + + // 给定条件 + String lockKey1 = "lock_1"; + String lockKey2 = "lock_2"; + System.out.println("测试参数 - 锁键1: " + lockKey1 + ", 锁键2: " + lockKey2); + + when(redisService.set(anyString(), anyString(), anyLong())).thenReturn(true); + System.out.println("模拟Redis set操作成功"); + + // 当调用时 + boolean lock1Acquired = lockHelper.tryLock(lockKey1, 30); + System.out.println("获取第一个锁: " + (lock1Acquired ? "成功" : "失败")); + + boolean lock2Acquired = lockHelper.tryLock(lockKey2, 30); + System.out.println("获取第二个锁: " + (lock2Acquired ? "成功" : "失败")); + + // 那么验证 + assertTrue(lock1Acquired, "第一个锁应该成功获取"); + assertTrue(lock2Acquired, "第二个锁应该成功获取"); + System.out.println("两个锁都成功获取"); + + // 验证它们是不同的键 + verify(redisService).set(eq("distributed_lock:" + lockKey1), anyString(), eq(30L)); + verify(redisService).set(eq("distributed_lock:" + lockKey2), anyString(), eq(30L)); + System.out.println("验证通过: 两个独立的锁键都被正确设置"); + System.out.println("测试完成: testMultipleLocksIndependence\n"); + } + + @Test + public void testThreadIsolation() throws InterruptedException { + System.out.println("开始执行: testThreadIsolation"); + + // 给定条件 + String lockKey = "thread_isolation_lock"; + ExecutorService executor = Executors.newFixedThreadPool(2); + CountDownLatch latch = new CountDownLatch(2); + AtomicInteger[] results = new AtomicInteger[]{new AtomicInteger(0), new AtomicInteger(0)}; + System.out.println("测试参数 - 锁键: " + lockKey + ", 线程数: 2"); + + when(redisService.set(anyString(), anyString(), anyLong())).thenReturn(true); + System.out.println("模拟Redis set操作成功"); + + // 当执行时 + System.out.println("启动两个线程竞争同一个锁"); + for (int i = 0; i < 2; i++) { + final int threadIndex = i; + executor.submit(() -> { + try { + System.out.println("线程[" + threadIndex + "] 尝试获取锁"); + if (lockHelper.tryLock(lockKey, 30)) { + int count = results[threadIndex].incrementAndGet(); + System.out.println("线程[" + threadIndex + "] 获取锁成功,计数: " + count); + // 持有锁一段时间 + Thread.sleep(100); + System.out.println("线程[" + threadIndex + "] 持有锁100ms后释放"); + lockHelper.releaseLock(lockKey); + System.out.println("线程[" + threadIndex + "] 释放锁"); + } else { + System.out.println("线程[" + threadIndex + "] 获取锁失败"); + } + } catch (InterruptedException e) { + System.out.println("线程[" + threadIndex + "] 被中断"); + Thread.currentThread().interrupt(); + } finally { + latch.countDown(); + System.out.println("线程[" + threadIndex + "] 执行完毕"); + } + }); + } + + boolean completed = latch.await(5, TimeUnit.SECONDS); + executor.shutdown(); + System.out.println("所有线程执行完成: " + (completed ? "正常结束" : "超时结束")); + + // 那么验证 - 两个线程都应该能够在不同时间获得锁 + int result0 = results[0].get(); + int result1 = results[1].get(); + assertEquals(1, result0, "线程0应该获得一次锁"); + assertEquals(1, result1, "线程1应该获得一次锁"); + System.out.println("验证通过: 线程0获得锁次数=" + result0 + ", 线程1获得锁次数=" + result1); + System.out.println("测试完成: testThreadIsolation\n"); + } +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/ShopActivityCutpriceService.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/ShopActivityCutpriceService.java index 30a64a88..8c958650 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/ShopActivityCutpriceService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/ShopActivityCutpriceService.java @@ -33,11 +33,11 @@ public interface ShopActivityCutpriceService extends IBaseService canDoOrderCutPriceActivity(Integer ac_id, Integer order_user_id); + Pair canDoOrderCutPriceActivity(Integer activity_id, Integer order_user_id); /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java index ebf700c7..ce6a23a2 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java @@ -25,6 +25,7 @@ import com.suisung.mall.common.modules.activity.ShopActivityGroupbooking; import com.suisung.mall.common.modules.activity.ShopActivityGroupbookingHistory; import com.suisung.mall.common.modules.store.ShopStoreActivityBase; import com.suisung.mall.common.utils.CheckUtil; +import com.suisung.mall.common.utils.DateTimeUtils; import com.suisung.mall.common.utils.I18nUtil; import com.suisung.mall.core.web.service.RedisService; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; @@ -314,7 +315,7 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl activityBaseList; QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("activity_state", StateCode.ACTIVITY_STATE_WAITING); - queryWrapper.le("activity_starttime", new Date()); + queryWrapper.in("activity_state", StateCode.ACTIVITY_STATE_WAITING, StateCode.ACTIVITY_STATE_NORMAL); +// queryWrapper.le("activity_starttime", new Date()); while (CollUtil.isNotEmpty(activityBaseList = shopStoreActivityBaseService.lists(queryWrapper, page, 20).getRecords())) { for (ShopStoreActivityBase storeActivityBase : activityBaseList) { + if (storeActivityBase.getActivity_state() != null + && storeActivityBase.getActivity_state().intValue() == StateCode.ACTIVITY_STATE_WAITING + && DateTimeUtils.isActivityTimeValid(storeActivityBase.getActivity_starttime(), storeActivityBase.getActivity_endtime(), new Date())) { + Boolean result = transactionTemplate.execute(status -> { + storeActivityBase.setActivity_state(StateCode.ACTIVITY_STATE_NORMAL); + Map activityBaseMap = Convert.toMap(String.class, Object.class, storeActivityBase); - Boolean result = transactionTemplate.execute(status -> { - storeActivityBase.setActivity_state(StateCode.ACTIVITY_STATE_NORMAL); - Map activityBaseMap = Convert.toMap(String.class, Object.class, storeActivityBase); + if (!shopStoreActivityBaseService.editActivityBase(storeActivityBase.getActivity_id(), activityBaseMap)) { + status.isRollbackOnly(); + return false; + } - if (!shopStoreActivityBaseService.editActivityBase(storeActivityBase.getActivity_id(), activityBaseMap)) { - status.isRollbackOnly(); - return false; + return true; + }); + + if (Boolean.FALSE.equals(result)) { + logger.error(String.format("activity_id : %s 开启出错", storeActivityBase.getActivity_id())); } - - return true; - }); - - if (Boolean.FALSE.equals(result)) { - logger.error(String.format("activity_id : %s 开启出错", storeActivityBase.getActivity_id())); } + + if (storeActivityBase.getActivity_state() != null + && storeActivityBase.getActivity_state().intValue() == StateCode.ACTIVITY_STATE_NORMAL + && !DateTimeUtils.isActivityTimeValid(storeActivityBase.getActivity_starttime(), storeActivityBase.getActivity_endtime(), new Date())) { + + Boolean result = transactionTemplate.execute(status -> { + storeActivityBase.setActivity_state(StateCode.ACTIVITY_STATE_FINISHED); + Map activityBaseMap = Convert.toMap(String.class, Object.class, storeActivityBase); + + if (!shopStoreActivityBaseService.editActivityBase(storeActivityBase.getActivity_id(), activityBaseMap)) { + status.isRollbackOnly(); + return false; + } + + return true; + }); + + if (Boolean.FALSE.equals(result)) { + logger.error(String.format("activity_id : %s 设置过期出错", storeActivityBase.getActivity_id())); + } + } + } try { @@ -65,8 +90,18 @@ public class UpdateActivityStatusJob extends QuartzJobBean { page++; } + // 砍价活动时间到,更新砍价订单的过期状态 + autoUpdateCutPriceStateJob(); + } + + /** + * 只针对:砍价活动时间到,更新砍价订单的过期状态 + */ + private void autoUpdateCutPriceStateJob() { + ShopActivityCutpriceService shopActivityCutpriceService = SpringUtil.getBean(ShopActivityCutpriceService.class); // 活动时间到更新砍价订单的过期状态 shopActivityCutpriceService.autoUpdateCutPriceStateJob(); - } + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 144bb79e..12d5cc15 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -1607,6 +1607,29 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(activityId, userId); + if (!canDoOrderCutPriceActivity.getFirst()) { + logger.error("检查活动是否达标:{}", canDoOrderCutPriceActivity.getSecond()); + throw new ApiException(I18nUtil._("活动已过期或未砍到底价,暂无法提交订单。")); + } + + cartData.put("ac_id", acId); // shop_activity_cutprice 活动参与记录的自增id + cartData.put("activity_id", activityId); + cartData.put("activity_type", StateCode.ACTIVITY_TYPE_CUTPRICE); + } + // 添加保存订单(关键方法) List orderIdRow = addOrder(cartData, true, false, null); @@ -1632,25 +1655,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(acId, userId); - if (!canDoOrderCutPriceActivity.getFirst()) { - logger.error(canDoOrderCutPriceActivity.getSecond()); - throw new ApiException(I18nUtil._("砍价活动未达标,请继续努力,再提交订单。")); - } - } // 判断是否拼团购买 if (gbId != null) { @@ -6680,6 +6684,10 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl=开始时间, 检查时间<=结束时间)", +// isValid); +// +// return isValid; +// } - if (checkTime == null) { - checkTime = new Date(); - } - - return !checkTime.before(starTime) && !checkTime.after(endTime); - } @Override public Map listsMarketing() { @@ -4460,10 +4467,9 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl() + .eq("activity_id", activity_id) + .set("activity_state", activity_state)); if (result) { logger.info("活动状态更新成功,活动ID: {},新状态: {}", activity_id, activity_state); @@ -4488,26 +4494,22 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl item_row = shopStoreActivityItemService.find(itemQueryWrapper); - List item_id_row = item_row.stream().filter(s->s.getActivity_item_state().equals(StateCode.ACTIVITY_STATE_NORMAL)).map(s -> s.getItem_id()).distinct().collect(Collectors.toList()); + List item_id_row = item_row.stream().filter(s -> s.getActivity_item_state().equals(StateCode.ACTIVITY_STATE_NORMAL)).map(s -> s.getItem_id()).distinct().collect(Collectors.toList()); List activity_id_row = item_row.stream().map(s -> s.getActivity_id()).distinct().collect(Collectors.toList()); List used_id_row = new ArrayList<>(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java index dd0b8419..cedc24aa 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java @@ -48,6 +48,7 @@ import com.suisung.mall.common.pojo.dto.StoreBizTimeInfoDTO; import com.suisung.mall.common.service.impl.BaiduMapServiceImpl; import com.suisung.mall.common.utils.*; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; +import com.suisung.mall.shop.activity.service.ShopActivityCutpriceService; import com.suisung.mall.shop.base.service.AccountBaseConfigService; import com.suisung.mall.shop.base.service.ShopBaseProductTagService; import com.suisung.mall.shop.base.service.ShopBaseStoreCategoryService; @@ -139,6 +140,11 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl lists = shopStoreActivityBaseService.lists(queryWrapper, 1, 500); + Page lists = shopStoreActivityBaseService.lists(queryWrapper, 1, 200); + + // Optimized version with improved code quality and readability + List filteredActivities = new ArrayList<>(); + for (ShopStoreActivityBase activity : lists.getRecords()) { + // Check if it's a cut-price activity that needs validation + if (activity.getActivity_type_id() != null + && activity.getActivity_type_id() == StateCode.ACTIVITY_TYPE_CUTPRICE) { + + // Validate cut-price activity stock and expiration + Pair checkStockResult = shopActivityCutpriceService.checkCutPriceExpiredAndStock(activity); + if (checkStockResult != null && !checkStockResult.getFirst()) { + // Insufficient stock or expired - update activity state to finished + shopStoreActivityBaseService.updateActivityState(activity.getActivity_id(), StateCode.ACTIVITY_STATE_FINISHED); + continue; // Skip adding this activity to results + } + } + + // Add valid activities to filtered list + filteredActivities.add(activity); + } + + // Update the page records with filtered results + lists.setRecords(filteredActivities); + Map data = toMobileResult(lists); ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); From 8f20e755fb41aaca58bca3a2c226034269e46d80 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Fri, 21 Nov 2025 15:01:01 +0800 Subject: [PATCH 23/81] =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=AF=AD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ShopActivityCutpriceServiceImpl.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java index ce6a23a2..bca71d1e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityCutpriceServiceImpl.java @@ -281,10 +281,10 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_id", user_id).eq("ac_id", ac_id); if (shopActivityCutpriceHistoryService.count(queryWrapper) > 0) { - return CommonResult.failed(I18nUtil._("您已经帮好友砍过价了!")); + return CommonResult.failed(I18nUtil._("您已帮好友砍过价了!")); } } catch (Exception e) { return CommonResult.failed(I18nUtil._("系统繁忙,请稍后再试!")); @@ -617,12 +617,12 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl queryWrapperHistory = new QueryWrapper<>(); @@ -701,7 +701,7 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl= productCount) { - return Pair.of(false, I18nUtil._("活动商品库存不足,请稍后再参与!")); + return Pair.of(false, I18nUtil._("活动商品不足,稍后再参与!")); } // 所有检查通过 From 9bc2d32c453599ff5b190ab3bd9562f9fbcf2185 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sat, 22 Nov 2025 01:54:00 +0800 Subject: [PATCH 24/81] =?UTF-8?q?=E5=95=86=E5=93=81=E5=BA=93=E8=A1=A8?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=20product=5Fshort=5Fname=20=E6=94=B9?= =?UTF-8?q?=E5=86=99=20sname=20=E7=AE=80=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/modules/library/LibraryProduct.java | 4 +++- mall-search/src/main/resources/dao/EsProductImage.xml | 6 +++--- .../resources/mapper/product/ShopProductImageMapper.xml | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java b/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java index 212c6a95..0caa0651 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java @@ -28,6 +28,9 @@ public class LibraryProduct implements Serializable { @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) private String name; + @ApiModelProperty(value = "商品简称,作为匹配关键字", example = "小米12 Pro") + private String sname; + @ApiModelProperty(value = "商品标题", example = "小米12 Pro") private String title; @@ -62,7 +65,6 @@ public class LibraryProduct implements Serializable { @ApiModelProperty(value = "商品卖点", example = "绿色有机") private String selling_point; - @ApiModelProperty(value = "商品介绍", example = "商品介绍") private String intro; diff --git a/mall-search/src/main/resources/dao/EsProductImage.xml b/mall-search/src/main/resources/dao/EsProductImage.xml index 6160290f..29f99f7f 100644 --- a/mall-search/src/main/resources/dao/EsProductImage.xml +++ b/mall-search/src/main/resources/dao/EsProductImage.xml @@ -16,7 +16,7 @@ lp.id, lp.barcode, lp.name, - lp.product_short_name, + lp.sname, lp.category, lp.thumb, ( @@ -37,7 +37,7 @@ lp.id, lp.barcode, lp.name, - lp.product_short_name, + lp.sname, lp.category, lp.thumb, ( @@ -60,7 +60,7 @@ lp.id, lp.barcode, lp.name, - lp.product_short_name, + lp.sname, lp.category, lp.thumb, ( diff --git a/mall-shop/src/main/resources/mapper/product/ShopProductImageMapper.xml b/mall-shop/src/main/resources/mapper/product/ShopProductImageMapper.xml index 2b885a43..10d0e652 100644 --- a/mall-shop/src/main/resources/mapper/product/ShopProductImageMapper.xml +++ b/mall-shop/src/main/resources/mapper/product/ShopProductImageMapper.xml @@ -161,7 +161,7 @@ shop_product_image spi INNER JOIN library_product lp ON - spi.product_short_name = lp.product_short_name + spi.product_short_name = lp.sname LEFT JOIN ( SELECT @@ -178,7 +178,7 @@ WHERE spi.product_from = '1005' AND spi.item_image_default = '1' - '' ]]> + '' ]]> )t )temp where @@ -213,7 +213,7 @@ shop_product_image spi INNER JOIN library_product lp ON - spi.product_short_name = lp.product_short_name + spi.product_short_name = lp.sname LEFT JOIN ( SELECT @@ -230,7 +230,7 @@ WHERE spi.product_from = '1005' AND spi.item_image_default = '1' - '' ]]> + '' ]]> )t )temp where From 9c8f78f3cf8c951ee69d837e86331a1c3aae7588 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Sat, 22 Nov 2025 10:38:02 +0800 Subject: [PATCH 25/81] =?UTF-8?q?=E5=BA=97=E9=93=BA=E8=A3=85=E4=BF=AE?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/modules/page/ShopPageApp.java | 14 ++ .../number/service/ShopNumberSeqService.java | 2 + .../impl/ShopNumberSeqServiceImpl.java | 40 +++- .../admin/ShopPageAppController.java | 185 ++++++++++++-- .../shop/page/service/ShopPageAppService.java | 5 + .../service/impl/ShopPageAppServiceImpl.java | 226 +++++++++++++++++- sql/shop/dev/20251121_dml.sql | 12 + 7 files changed, 465 insertions(+), 19 deletions(-) create mode 100644 sql/shop/dev/20251121_dml.sql diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java index 553e55a5..ae38892a 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java @@ -1,6 +1,7 @@ package com.suisung.mall.common.modules.page; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -67,5 +68,18 @@ public class ShopPageApp implements Serializable { @ApiModelProperty(value = "是否使用(BOOL):0-否;1-是") private Integer app_is_use; + @ApiModelProperty(value = "模板编号,用于模板市场") + private Integer app_template_id; + @ApiModelProperty(value = "是否收费0否,1是") + private String is_pay; + + @ApiModelProperty(value = "是否发布0否,1是") + private String is_pulish; + + @TableField(exist = false) + private String tpl_label; + + @ApiModelProperty(value = "市场展示图片,用,隔开") + private String app_market_images; } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java index 34128812..662505bb 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java @@ -37,4 +37,6 @@ public interface ShopNumberSeqService extends IBaseService { List getBatchLibraryProductId(int batchSize); void clearKeyLibraryProductId(); + + List batchCreateShopPageBaseNextNo(int batchSize); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java index 4e8c55d8..20b9bb23 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java @@ -8,6 +8,7 @@ import com.suisung.mall.common.feignService.AccountService; import com.suisung.mall.common.modules.base.ShopBaseProductSpec; import com.suisung.mall.common.modules.library.LibraryProduct; import com.suisung.mall.common.modules.number.ShopNumberSeq; +import com.suisung.mall.common.modules.page.ShopPageBase; import com.suisung.mall.common.modules.product.ShopProductBase; import com.suisung.mall.common.modules.product.ShopProductItem; import com.suisung.mall.common.modules.product.ShopProductSpecItem; @@ -17,6 +18,7 @@ import com.suisung.mall.shop.base.service.ShopBaseProductSpecService; import com.suisung.mall.shop.library.service.LibraryProductService; import com.suisung.mall.shop.number.mapper.ShopNumberSeqMapper; import com.suisung.mall.shop.number.service.ShopNumberSeqService; +import com.suisung.mall.shop.page.service.ShopPageBaseService; import com.suisung.mall.shop.product.service.ShopProductBaseService; import com.suisung.mall.shop.product.service.ShopProductItemService; import com.suisung.mall.shop.product.service.ShopProductSpecItemService; @@ -78,7 +80,8 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl batchCreateShopPageBaseNextNo(int batchSize) { + // 定义锁的key,这个key在所有服务实例中必须一致 + String lockKey = "LOCK:" + RedisKey.STOREDATASHOPBASEPAGE; + // 2. 获取分布式锁对象 + RLock lock = redissonClient.getLock(lockKey); + boolean isLocked = false; + long start = 0; + try { + isLocked=lock.tryLock(2,30,TimeUnit.SECONDS); + if (!isLocked) { + // 获取锁失败,可以根据业务逻辑进行重试或抛出异常 + throw new ApiException("系统繁忙,请稍后再试"); + } + log.info("成功获得锁:{}",lockKey); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select("max(page_id) as page_id"); + ShopPageBase shopPageBase = shopPageBaseService.getOne(queryWrapper); + if (null != shopPageBase) { + start = shopPageBase.getPage_id(); + } + return LongStream.rangeClosed(start + 1, start + batchSize).boxed().collect(Collectors.toList()); + } catch (InterruptedException e) { + throw new ApiException(e); + }finally { + // 5. 最终检查并释放锁,确保锁一定被释放 + if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) { + lock.unlock(); + } + log.info("成功释放锁:{}",lockKey); + } + } + /** * 初始化主键 */ @@ -500,4 +536,6 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl items =null; try { - data_arr = cloundService.getAppTpl(accountBaseConfigService.getConfig("service_user_id", 0), accountBaseConfigService.getConfig("service_app_key", ""), null); + // data_arr = cloundService.getAppTpl(accountBaseConfigService.getConfig("service_user_id", 0), accountBaseConfigService.getConfig("service_app_key", ""), null); + if(user.isStore()) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id", user.getStore_id()); + List shopPageAppList= shopPageAppService.list(queryWrapper); + if(shopPageAppList.isEmpty()) { + String resultStr= accountBaseConfigService.getSystemConfig("service_app_tpl"); + JSONObject jsonObject = JSONUtil.parseObj(resultStr); + data_arr = (Map)jsonObject.get("data"); + items_arr = (JSONArray) data_arr.get("items"); + items = JSONUtil.toList(items_arr, Map.class); + }else { + Gson gson = new Gson(); + String gsonStrList= gson.toJson(shopPageAppList); + items = JSONUtil.toList(gsonStrList, Map.class); + } + }else { + String resultStr= accountBaseConfigService.getSystemConfig("service_app_tpl"); + JSONObject jsonObject = JSONUtil.parseObj(resultStr); + data_arr = (Map)jsonObject.get("data"); + items_arr = (JSONArray) data_arr.get("items"); + items = JSONUtil.toList(items_arr, Map.class); + } + } catch (Exception e) { throw new RuntimeException(e); } - JSONArray items_arr = (JSONArray) data_arr.get("items"); - List items = JSONUtil.toList(items_arr, Map.class); Map current_tpl = new HashMap(); @@ -91,19 +113,18 @@ public class ShopPageAppController extends BaseControllerImpl { while (it.hasNext()) { Map item = it.next(); Integer tpl_id = Convert.toInt(item.get("tpl_id")); - String tpl_label = item.get("tpl_label").toString(); - + String tpl_label =CommonUtil.getTplLable(tpl_id); + //String tpl_label = item.get("tpl_label").toString(); + item.put("tpl_label",tpl_label); if (user.isStore()) { //读取店铺信息store_template ShopStoreInfo shopStoreInfo = shopStoreInfoService.get(user.getStore_id()); - if (tpl_id > 1000 || tpl_id == 109 || tpl_id == 105 || tpl_id == 10/* || tpl_id == 107*/) { it.remove(); continue; } - - - if (shopStoreInfo.getStore_template().equals(tpl_label)) { + String appId= String.valueOf(item.get("app_id")); + if (shopStoreInfo.getStore_template().equals(appId)) { current_tpl = item; } } else { @@ -163,7 +184,7 @@ public class ShopPageAppController extends BaseControllerImpl { @ApiOperation(value = "店铺风格表-编辑app模版", notes = "店铺风格表-编辑app模版") @RequestMapping(value = "/editApp", method = RequestMethod.GET) public ModelAndView diy(@RequestParam(name = "tpl_id", defaultValue = "1012") Integer tpl_id) { - UserDto user = getCurrentUser(); + UserDto user = ContextUtil.getCurrentUser(); if (user == null) { throw new ApiUserException(I18nUtil._("用户信息异常!")); } @@ -355,5 +376,135 @@ public class ShopPageAppController extends BaseControllerImpl { return CommonResult.failed(); } + + /** + * 店铺装修复制 + * + * @param sourceStoreId + * @param targetStoreId + * @return + */ + @RequestMapping(value = "/copyDiyByStore", method = RequestMethod.POST) + public CommonResult copyDiyByStore(@RequestParam(name = "sourceStoreId") Integer sourceStoreId, + @RequestParam(name = "targetStoreId") Integer targetStoreId) { + UserDto user = ContextUtil.getCurrentUser(); + if (user == null) { + throw new ApiUserException(I18nUtil._("用户信息异常!")); + } + + return CommonResult.success(shopPageAppService.copyDiyByStore(sourceStoreId, targetStoreId)); + } + + /** + * 店铺装修复制 + * + * @param appId 复制模板的id + * @param newAppName 新模板名称 + * @return + */ + @RequestMapping(value = "/copyDiyByAppId", method = RequestMethod.POST) + public CommonResult copyDiyByAppId(@RequestParam(name = "appId") Integer appId, + @RequestParam(name = "appName") String newAppName) { + UserDto user = ContextUtil.getCurrentUser(); + if (user == null) { + throw new ApiUserException(I18nUtil._("用户信息异常!")); + } + + return CommonResult.success(shopPageAppService.copyDiyByAppId(appId, newAppName)); + } + + /** + * 上传模板市场 + * @param appId 模板的id + * @param isPublish 发布状态 + * @return + */ + @RequestMapping(value = "/pageAppPubish", method = RequestMethod.POST) + public CommonResult pageAppPubish(@RequestParam(name = "appId") Integer appId, + @RequestParam(name = "isPublish") String isPublish) { + UserDto user = ContextUtil.getCurrentUser(); + if (user == null) { + throw new ApiUserException(I18nUtil._("用户信息异常!")); + } + ShopPageApp shopPageApp= shopPageAppService.get(appId); + if(null == shopPageApp){ + return CommonResult.failed("不存在模板"); + } + String storeId= user.getStore_id(); + if(user.isPlatform()){ + shopPageApp.setIs_pulish(isPublish); + shopPageAppService.edit(shopPageApp); + }else { + if(!Objects.equals(storeId, String.valueOf(shopPageApp.getStore_id()))){ + return CommonResult.failed("权限不足"); + } + shopPageApp.setIs_pulish(isPublish); + shopPageAppService.edit(shopPageApp); + } + + return CommonResult.success("操作成功"); + } + + + /** + * 分页查询市场模板 + * @param pageNum + * @param pageSize + * @return + */ + @ApiOperation(value = "店铺风格表-分页查询市场模板", notes = "店铺风格表-分页查询市场模板") + @RequestMapping(value = "/listMarketPage", method = RequestMethod.GET) + public Page listMarketPage(@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(name = "pageSize", defaultValue = "100") Integer pageSize) { + UserDto user = ContextUtil.getCurrentUser(); + if (user == null) { + throw new ApiException("无权限"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("is_pulish", "1"); + String appName= getParameter("appName"); + if(StringUtils.isNotEmpty(appName)){ + queryWrapper.like("app_name", appName); + } + Page shopPageAppPage= shopPageAppService.lists(queryWrapper,pageNum,pageSize); + List shopPageAppPageList = shopPageAppPage.getRecords(); + for (ShopPageApp shopPageApp : shopPageAppPageList) { + String tpl_label = CommonUtil.getTplLable(shopPageApp.getTpl_id()); + shopPageApp.setTpl_label(tpl_label); + } + shopPageAppPage.setRecords(shopPageAppPageList); + return shopPageAppPage; + } + + /** + * 市场app编辑 + * @param shopPageApp + * @return + */ + @ApiOperation(value = "店铺风格表-市场app编辑", notes = "店铺风格表-市场app编辑") + @RequestMapping(value = "/editPageApp", method = RequestMethod.POST) + public CommonResult editPageApp(@RequestBody ShopPageApp shopPageApp) { + UserDto user = ContextUtil.getCurrentUser(); + if (user == null) { + throw new ApiException("无权限"); + } + if(null==shopPageApp.getApp_id()){ + throw new ApiException("修改的appid不能为空"); + } + ShopPageApp editShopPageApp= shopPageAppService.get(shopPageApp.getApp_id()); + if(null==editShopPageApp){ + return CommonResult.failed("不存在模板"); + } + if(Integer.valueOf(user.getStore_id())!=editShopPageApp.getStore_id()){ + return CommonResult.failed("不能跨店编辑"); + } + editShopPageApp.setApp_name(shopPageApp.getApp_name()); + editShopPageApp.setIs_pulish(shopPageApp.getIs_pulish()); + editShopPageApp.setApp_market_images(shopPageApp.getApp_market_images()); + editShopPageApp.setTpl_image(shopPageApp.getTpl_image()); + shopPageAppService.edit(editShopPageApp); + return CommonResult.success(); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java index da5981b7..6cba0730 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java @@ -1,5 +1,6 @@ package com.suisung.mall.shop.page.service; +import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.page.ShopPageApp; import com.suisung.mall.core.web.service.IBaseService; import org.springframework.web.servlet.ModelAndView; @@ -53,4 +54,8 @@ public interface ShopPageAppService extends IBaseService { Map getModuleTpl(); Map getPageModule(Long page_id); + + CommonResult copyDiyByStore(Integer sourceStoreId, Integer tpl_id); + + CommonResult copyDiyByAppId(Integer appId,String a); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java index 369de289..f091b627 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java @@ -9,6 +9,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.api.ResultCode; import com.suisung.mall.common.constant.ConfigConstant; import com.suisung.mall.common.domain.UserDto; @@ -18,26 +19,33 @@ import com.suisung.mall.common.modules.base.ShopBaseProductCategory; import com.suisung.mall.common.modules.base.ShopPageModule; import com.suisung.mall.common.modules.page.ShopPageApp; import com.suisung.mall.common.modules.page.ShopPageBase; +import com.suisung.mall.common.modules.product.ShopPageUserForm; import com.suisung.mall.common.modules.store.ShopStoreInfo; import com.suisung.mall.common.utils.CheckUtil; +import com.suisung.mall.common.utils.ContextUtil; import com.suisung.mall.common.utils.I18nUtil; import com.suisung.mall.core.web.service.CloundService; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.base.service.AccountBaseConfigService; import com.suisung.mall.shop.base.service.ShopBaseProductCategoryService; import com.suisung.mall.shop.config.CookieUtil; +import com.suisung.mall.shop.number.service.ShopNumberSeqService; import com.suisung.mall.shop.page.mapper.ShopPageAppMapper; import com.suisung.mall.shop.page.service.ShopPageAppService; import com.suisung.mall.shop.page.service.ShopPageBaseService; import com.suisung.mall.shop.page.service.ShopPageModuleService; +import com.suisung.mall.shop.product.service.ShopPageUserFormService; +import com.suisung.mall.shop.product.service.impl.ShopPageUserFormServiceImpl; import com.suisung.mall.shop.store.service.ShopStoreInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.servlet.ModelAndView; +import javax.security.sasl.AuthenticationException; import javax.servlet.http.Cookie; import java.util.*; +import java.util.stream.Collectors; import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser; @@ -73,6 +81,11 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl shopStoreInfoQueryWrapper = new QueryWrapper<>(); + shopStoreInfoQueryWrapper.eq("store_id", sourceStoreId); + List sourceShopStore= shopStoreInfoService.list(shopStoreInfoQueryWrapper); + if(sourceShopStore.isEmpty()){ + return CommonResult.failed("来源店铺不存在"); + } + shopStoreInfoQueryWrapper.clear(); + shopStoreInfoQueryWrapper.eq("store_id", targetStoreId); + List targeShopStore= shopStoreInfoService.list(shopStoreInfoQueryWrapper); + if(targeShopStore.isEmpty()){ + return CommonResult.failed("目标店铺不存在"); + } + + QueryWrapper sourceShopPageAppQueryWrapper = new QueryWrapper<>(); + sourceShopPageAppQueryWrapper.eq("store_id", sourceStoreId); + sourceShopPageAppQueryWrapper.eq("app_is_use",1); + List sourceShopPageApps= shopPageAppService.list(sourceShopPageAppQueryWrapper); + if(sourceShopPageApps.isEmpty()){ + return CommonResult.failed("来源店铺不存在模板"); + } + + sourceShopPageAppQueryWrapper.clear(); + sourceShopPageAppQueryWrapper.eq("store_id", targetStoreId); + List targetShopPageApps= shopPageAppService.list(sourceShopPageAppQueryWrapper); + ShopPageApp shopPageApp=null; + if(targetShopPageApps.isEmpty()){ + shopPageApp= sourceShopPageApps.get(0); + shopPageApp.setStore_id(targetStoreId); + shopPageApp.setApp_id(null); + shopPageAppService.save(shopPageApp); + }else { + shopPageApp=targetShopPageApps.get(0); + shopPageApp.setApp_code(sourceShopPageApps.get(0).getApp_code()); + } + + QueryWrapper sourceShopPageBaseQueryWrapper = new QueryWrapper<>(); + sourceShopPageBaseQueryWrapper.eq("store_id", sourceStoreId); + List sourceShopPageBases= shopPageBaseService.list(sourceShopPageBaseQueryWrapper); + if(sourceShopPageBases.isEmpty()){ + return CommonResult.failed("原店铺不存在模板复制"); + } + QueryWrapper targetShopPageBaseQueryWrapper = new QueryWrapper<>(); + targetShopPageBaseQueryWrapper.eq("store_id", targetStoreId); + List targetShopPageBases= shopPageBaseService.list(targetShopPageBaseQueryWrapper); + + List sourceAppIdList= sourceShopPageBases.stream().map(ShopPageBase::getPage_id).collect(Collectors.toList()); + List newShopPageBaseIdList= shopNumberSeqService.batchCreateShopPageBaseNextNo(sourceAppIdList.size()); + + //删除目标appid + if(!targetShopPageBases.isEmpty()){ + //shopPageAppService.remove(targetShopPageBases.get(0).getApp_id()); + List shopPageBasesIds = targetShopPageBases.stream() + .map(ShopPageBase::getPage_id) + .collect(Collectors.toList()); + shopPageBaseService.removeBatchByIds(shopPageBasesIds); + } + + Map shopPageIdsouceTargetMap=getTargetPageIdMap(sourceAppIdList,newShopPageBaseIdList); + ShopPageApp finalShopPageApp = shopPageApp; + + sourceShopPageBases= sourceShopPageBases.stream().peek(shopPageBase -> { + shopPageBase.setPage_id(shopPageIdsouceTargetMap.get(shopPageBase.getPage_id())); + shopPageBase.setApp_id(finalShopPageApp.getApp_id()); + shopPageBase.setStore_id(targetStoreId); + }).collect(Collectors.toList()); + shopPageBaseService.saveBatch(sourceShopPageBases,sourceShopPageBases.size()); + + //赋值模块 + QueryWrapper shopPageModuleQueryWrapper = new QueryWrapper<>(); + shopPageModuleQueryWrapper.in("page_id", sourceAppIdList); + List sourceShopPageModuleList= shopPageModuleService.list(shopPageModuleQueryWrapper); + if(!sourceShopPageModuleList.isEmpty()){ + sourceShopPageModuleList=sourceShopPageModuleList.stream().peek(shopPageModule -> { + shopPageModule.setPm_id(null); + shopPageModule.setPage_id(shopPageIdsouceTargetMap.get(shopPageModule.getPage_id())); + }).collect(Collectors.toList()); + shopPageModuleService.saveBatch(sourceShopPageModuleList,sourceShopPageModuleList.size()); + } + + //动态表单复制,start + //1有先删除 + List shopPageUserFormsTarget= shopPageUserFormService.list(new QueryWrapper().eq("store_id",targetStoreId)); + if(!shopPageUserFormsTarget.isEmpty()){ + List shopPageUserFormIds=shopPageUserFormsTarget.stream().map(ShopPageUserForm::getId).collect(Collectors.toList()); + shopPageUserFormService.removeBatchByIds(shopPageUserFormIds,shopPageUserFormIds.size()); + } + //查询来源是否有表单,有就复制 + List shopPageUserFormsSource= shopPageUserFormService.list(new QueryWrapper().eq("store_id",sourceStoreId)); + if(!shopPageUserFormsSource.isEmpty()){ + shopPageUserFormsSource=shopPageUserFormsSource.stream().peek(shopPageUserForm -> { + shopPageUserForm.setId(null); + shopPageUserForm.setPage_id(shopPageIdsouceTargetMap.get(shopPageUserForm.getPage_id())); + }).collect(Collectors.toList()); + shopPageUserFormService.saveBatch(shopPageUserFormsSource,shopPageUserFormsSource.size()); + } + //动态表单复制,end + + return CommonResult.failed("diy装修模板复制成功"); + } + + @Override + public CommonResult copyDiyByAppId(Integer appId,String appName) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto==null){ + return CommonResult.failed("用户没有登录"); + } + Integer curentStoreId=Integer.valueOf(userDto.getStore_id()); + QueryWrapper shopStoreInfoQueryWrapper = new QueryWrapper<>(); + shopStoreInfoQueryWrapper.eq("store_id", curentStoreId); + List sourceShopStore= shopStoreInfoService.list(shopStoreInfoQueryWrapper); + if(sourceShopStore.isEmpty()){ + return CommonResult.failed("店铺不存在"); + } + + QueryWrapper sourceShopPageAppQueryWrapper = new QueryWrapper<>(); + sourceShopPageAppQueryWrapper.eq("app_id", appId); + List sourceShopPageApps= shopPageAppService.list(sourceShopPageAppQueryWrapper); + if(sourceShopPageApps.isEmpty()){ + return CommonResult.failed("不存在模板"); + } + ShopPageApp shopPageApp=sourceShopPageApps.get(0); + Integer appTemplateId=shopPageApp.getApp_template_id(); + shopPageApp= sourceShopPageApps.get(0); + shopPageApp.setStore_id(curentStoreId); + shopPageApp.setApp_template_id(appTemplateId); + shopPageApp.setApp_id(null); + shopPageApp.setApp_is_use(0); + shopPageApp.setApp_name(appName); + shopPageApp.setUser_id(userDto.getId()); + shopPageAppService.save(shopPageApp); + + QueryWrapper sourceShopPageBaseQueryWrapper = new QueryWrapper<>(); + sourceShopPageBaseQueryWrapper.eq("app_id", appId); + List sourceShopPageBases= shopPageBaseService.list(sourceShopPageBaseQueryWrapper); + if(sourceShopPageBases.isEmpty()){ + return CommonResult.failed("不存在复制页面模板"); + } + + List sourceAppIdList= sourceShopPageBases.stream().map(ShopPageBase::getPage_id).collect(Collectors.toList()); + List newShopPageBaseIdList= shopNumberSeqService.batchCreateShopPageBaseNextNo(sourceAppIdList.size()); + + Map shopPageIdsouceTargetMap=getTargetPageIdMap(sourceAppIdList,newShopPageBaseIdList); + ShopPageApp finalShopPageApp = shopPageApp; + sourceShopPageBases= sourceShopPageBases.stream().peek(shopPageBase -> { + shopPageBase.setPage_id(shopPageIdsouceTargetMap.get(shopPageBase.getPage_id())); + shopPageBase.setApp_id(finalShopPageApp.getApp_id()); + shopPageBase.setStore_id(curentStoreId); + }).collect(Collectors.toList()); + shopPageBaseService.saveBatch(sourceShopPageBases,sourceShopPageBases.size()); + + //复制模块 + QueryWrapper shopPageModuleQueryWrapper = new QueryWrapper<>(); + shopPageModuleQueryWrapper.in("page_id", sourceAppIdList); + List sourceShopPageModuleList= shopPageModuleService.list(shopPageModuleQueryWrapper); + if(!sourceShopPageModuleList.isEmpty()){ + sourceShopPageModuleList=sourceShopPageModuleList.stream().peek(shopPageModule -> { + shopPageModule.setPm_id(null); + shopPageModule.setPage_id(shopPageIdsouceTargetMap.get(shopPageModule.getPage_id())); + }).collect(Collectors.toList()); + shopPageModuleService.saveBatch(sourceShopPageModuleList,sourceShopPageModuleList.size()); + } + + //动态表单复制,start + //查询来源是否有表单,有就复制 + List shopPageUserFormsSource= shopPageUserFormService.list(new QueryWrapper().eq("page_id",sourceAppIdList)); + if(!shopPageUserFormsSource.isEmpty()){ + shopPageUserFormsSource=shopPageUserFormsSource.stream().peek(shopPageUserForm -> { + shopPageUserForm.setId(null); + shopPageUserForm.setPage_id(shopPageIdsouceTargetMap.get(shopPageUserForm.getPage_id())); + }).collect(Collectors.toList()); + shopPageUserFormService.saveBatch(shopPageUserFormsSource,shopPageUserFormsSource.size()); + } + //动态表单复制,end + + return CommonResult.failed("diy装修模板复制成功"); + } + + + /** + * 生产新的id + * @param sourceShopPageIdList + * @param targetShopPageIdList + * @return + */ + private Map getTargetPageIdMap(List sourceShopPageIdList, List targetShopPageIdList){ + Map resultMap=new HashMap<>(); + for(int i=0; i Date: Sat, 22 Nov 2025 10:44:42 +0800 Subject: [PATCH 26/81] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BA=97=E9=93=BA?= =?UTF-8?q?=E8=A3=85=E4=BF=AE=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/shop/dev/20251122_ddl.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 sql/shop/dev/20251122_ddl.sql diff --git a/sql/shop/dev/20251122_ddl.sql b/sql/shop/dev/20251122_ddl.sql new file mode 100644 index 00000000..4f0b57ad --- /dev/null +++ b/sql/shop/dev/20251122_ddl.sql @@ -0,0 +1,5 @@ +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/copyDiyByStore', 'index', 'master', '', '0', '/admin/shop/shop-page-app/copyDiyByStore','diy复制-根据店铺'); +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/copyDiyByAppId', 'index', 'master', '', '0', '/admin/shop/shop-page-app/copyDiyByAppId','diy复制-根据appid'); +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/pageAppPubish', 'index', 'master', '', '0', '/admin/shop/shop-page-app/pageAppPubish','diy上传模板市场'); +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/editPageApp', 'index', 'master', '', '0', '/admin/shop/shop-page-app/editPageApp','diy编辑app页面'); +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/listMarketPage', 'index', 'master', '', '0', '/admin/shop/shop-page-app/listMarketPage','diy市场模板查询列表'); \ No newline at end of file From de19921581acd12d891f7b9e6cdbb0535f329c45 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Sat, 22 Nov 2025 10:51:03 +0800 Subject: [PATCH 27/81] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BA=97=E9=93=BA?= =?UTF-8?q?=E8=A3=85=E4=BF=AE=E8=B7=AF=E7=94=B1-=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../suisung/mall/common/utils/CommonUtil.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java b/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java index f46995aa..7ccb6d9c 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java @@ -476,6 +476,41 @@ public class CommonUtil { return result; } + /** + * 获取shopApp的lable + * @param tpl_id + * @return + */ + public static String getTplLable(Integer tpl_id) { + String tpl_label=""; + if (tpl_id == 101) { + tpl_label = "shop1"; + } + if (tpl_id == 102) { + tpl_label = "shop2"; + } + if (tpl_id == 103) { + tpl_label = "shop3"; + } + if (tpl_id == 104) { + tpl_label = "shop4"; + } + if (tpl_id == 105) { + tpl_label = "shop5"; + } + if (tpl_id == 106) { + tpl_label = "shop6"; + } + if (tpl_id == 107) { + tpl_label = "shop7"; + } + if (tpl_id == 109) { + tpl_label = "shop9"; + } + return tpl_label; + } + + public static void main(String[] args) { System.out.println("测试1分钱分配:"); System.out.println(calculateProfitSharing(9800, new BigDecimal("0.94"), new BigDecimal("0.2"), new BigDecimal("0"))); From 32bd2fab91dcb0b7e47045ef31edd29b8e6a667a Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Mon, 24 Nov 2025 00:11:34 +0800 Subject: [PATCH 28/81] =?UTF-8?q?=E8=A3=85=E4=BF=AE=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20=E5=88=9B=E5=BB=BA=E6=97=B6=E9=97=B4=E5=92=8C?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E6=97=B6=E9=97=B4=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/suisung/mall/common/modules/page/ShopPageBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageBase.java index f061060c..5075d865 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageBase.java @@ -10,6 +10,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.Date; /** *

@@ -135,5 +136,9 @@ public class ShopPageBase implements Serializable { @ApiModelProperty(value = "信息发布(BOOL):0-否;1-是") private Integer page_message; + @ApiModelProperty(value = "创建时间") + private Date created_at; + @ApiModelProperty(value = "最后更新时间") + private Date updated_at; } From 3802044eeac5516834a7452bf12c626d6cd5a507 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Mon, 24 Nov 2025 15:03:42 +0800 Subject: [PATCH 29/81] =?UTF-8?q?=E5=AF=B9=E8=AF=9Dsession=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onchat/MallsuiteImSocketHandler.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java index e2621931..5141d15d 100644 --- a/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java +++ b/mall-im/src/main/java/com/suisung/mall/im/common/websocket/service/onchat/MallsuiteImSocketHandler.java @@ -3,6 +3,7 @@ package com.suisung.mall.im.common.websocket.service.onchat; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; import cn.hutool.json.JSONUtil; +import com.suisung.mall.common.utils.StringUtils; import com.suisung.mall.im.common.websocket.service.DistributedMessageService; import com.suisung.mall.im.common.websocket.service.DistributedSessionService; import com.suisung.mall.im.common.websocket.service.LocalSessionManager; @@ -191,13 +192,13 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { if (session.isOpen()) { session.close(); } - logger.debug("websocket connection closed......"); + logger.info("websocket connection closed......{}",session); cleanupSession(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { - logger.debug("websocket connection closed......"); + logger.info("websocket connection closed......{}",session); cleanupSession(session); } @@ -207,14 +208,20 @@ public class MallsuiteImSocketHandler implements WebSocketHandler { private void cleanupSession(WebSocketSession session) { String loginUserId = String.valueOf(session.getAttributes().get("user_id")) ; String sessionId = session.getId(); - String groupId = (String) session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY); - + String groupId =""; + if(null!=session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)){ + groupId = String.valueOf(session.getAttributes().get(Constants.WEBSOCKET_GROUP_KEY)) ; + } // 从本地管理移除 if(localSessionManager.getUserSessions()==null){ localSessionManager.setUserSessions(new ConcurrentHashMap<>()); } - localSessionManager.removeUserSession(loginUserId, session); - if (groupId != null) { + + if(StringUtils.isNotEmpty(loginUserId)){ + localSessionManager.removeUserSession(loginUserId, session); + } + + if (StringUtils.isNotEmpty(groupId)) { localSessionManager.removeGroupSession(groupId, session); } From b628fffca7c83f312f1ec035b12ae8c935b26f92 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Mon, 24 Nov 2025 17:30:26 +0800 Subject: [PATCH 30/81] =?UTF-8?q?=E5=9B=BE=E5=BA=93=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=96=B0=E5=A2=9E=E8=A3=85=E4=BF=AE?= =?UTF-8?q?=E7=A9=BA=E7=99=BD=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/library/LibraryProduct.java | 11 + .../modules/library/LibraryProductImage.java | 6 + .../mall/common/modules/page/ShopPageApp.java | 2 +- .../common/modules/sync/StoreDbConfig.java | 4 + .../common/pojo/dto/LibraryProductDTO.java | 9 +- .../service/LibraryProductImageService.java | 5 +- .../service/LibraryProductService.java | 3 + .../service/impl/LibraryProductImpl.java | 344 +++++++++++++++++- .../admin/ShopPageAppController.java | 22 +- .../mall/shop/page/service/OssService.java | 1 + .../page/service/impl/OssServiceImpl.java | 28 ++ .../mall/shop/sync/keymanage/RedisKey.java | 2 + sql/shop/dev/20251122_dml.sql | 1 + sql/shop/dev/20251124_ddl.sql | 3 + 14 files changed, 424 insertions(+), 17 deletions(-) create mode 100644 sql/shop/dev/20251122_dml.sql create mode 100644 sql/shop/dev/20251124_ddl.sql diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java b/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java index 0caa0651..8824bbff 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProduct.java @@ -11,6 +11,7 @@ import lombok.NoArgsConstructor; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; +import java.util.List; @Data @Builder @@ -32,6 +33,7 @@ public class LibraryProduct implements Serializable { private String sname; @ApiModelProperty(value = "商品标题", example = "小米12 Pro") + @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) private String title; @ApiModelProperty(value = "条形码/Barcode", example = "6923450657713") @@ -39,9 +41,11 @@ public class LibraryProduct implements Serializable { private String barcode; @ApiModelProperty(value = "第一级分类", example = "生鲜") + @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) private String category_1st; @ApiModelProperty(value = "第二级分类", example = "牛肉") + @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) private String category_2nd; @ApiModelProperty(value = "商品分类", example = "牛肉") @@ -94,4 +98,11 @@ public class LibraryProduct implements Serializable { @ApiModelProperty(value = "更新时间", example = "2023-01-02 15:30:00") @TableField(value = "updated_at") private Date updatedAt; + +// @ApiModelProperty(value = "来源ID", example = "vendor_001") +// @TableField(value = "product_short_name", updateStrategy = FieldStrategy.NOT_EMPTY) +// private String productShortName; + + @TableField(exist = false) + private List product_image_list; } \ No newline at end of file diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProductImage.java b/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProductImage.java index e8346d41..f084ab02 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProductImage.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/library/LibraryProductImage.java @@ -9,6 +9,7 @@ package com.suisung.mall.common.modules.library; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -34,13 +35,16 @@ public class LibraryProductImage implements Serializable { private Long id; @ApiModelProperty(value = "商品ID", position = 2, example = "1001") + @TableField(value = "product_id") private Long productId; @ApiModelProperty(value = "图片地址", position = 3, example = "/media/images/product/1001.jpg") + @TableField(value = "image_url") private String imageUrl; @ApiModelProperty(value = "是否主图 1-主图 0-副图", position = 4, example = "1") + @TableField(value = "is_main") private Boolean isMain; @ApiModelProperty(value = "排序值,越小越前面", position = 5, example = "10") @@ -50,8 +54,10 @@ public class LibraryProductImage implements Serializable { private Integer status; @ApiModelProperty(value = "创建时间", position = 7, example = "2023-01-01 12:30:00") + @TableField(value = "created_at") private Date createdAt; @ApiModelProperty(value = "更新时间", position = 8, example = "2023-01-01 13:15:00") + @TableField(value = "updated_at") private Date updatedAt; } \ No newline at end of file diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java index ae38892a..ff97f6ec 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java @@ -80,6 +80,6 @@ public class ShopPageApp implements Serializable { @TableField(exist = false) private String tpl_label; - @ApiModelProperty(value = "市场展示图片,用,隔开") + @ApiModelProperty(value = "市场展示图片,[{'imageUrl:'','content':''},{}]") private String app_market_images; } diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/sync/StoreDbConfig.java b/mall-common/src/main/java/com/suisung/mall/common/modules/sync/StoreDbConfig.java index 230b2337..608fd3bc 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/sync/StoreDbConfig.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/sync/StoreDbConfig.java @@ -142,4 +142,8 @@ public class StoreDbConfig implements Serializable { @TableField(value = "automatic",updateStrategy = FieldStrategy.NOT_EMPTY) @ApiModelProperty(value = "默认次日补全库存(思迅同步时配置)") private Integer automatic; + + @TableField(value = "client_version",updateStrategy = FieldStrategy.NOT_EMPTY) + @ApiModelProperty(value = "客户端版本:1商云10,2商瑞9.7,3商祺") + private String clientVersion; } \ No newline at end of file diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LibraryProductDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LibraryProductDTO.java index ecc9d5ad..526db52c 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LibraryProductDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LibraryProductDTO.java @@ -42,7 +42,7 @@ public class LibraryProductDTO implements Serializable { if (this.product_image_list != null) { for (ProductImage image : this.product_image_list) { if (image != null) { - image.image_url = addDomainPrefix(imageDomain, image.getImage_url()); + image.imageUrl = addDomainPrefix(imageDomain, image.getImageUrl()); } } } @@ -66,9 +66,10 @@ public class LibraryProductDTO implements Serializable { @EqualsAndHashCode(callSuper = false) @ApiModel(value = "商品库的商品图片", description = "商品库的商品图片") public static class ProductImage implements Serializable { - private Long product_id; - private String image_url; - private Integer is_main; + private Long id; + private Long productId; + private String imageUrl; + private Integer isMain; private Integer seq; } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductImageService.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductImageService.java index df7cfb46..f822fe86 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductImageService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductImageService.java @@ -8,5 +8,8 @@ package com.suisung.mall.shop.library.service; -public interface LibraryProductImageService { +import com.suisung.mall.common.modules.library.LibraryProductImage; +import com.suisung.mall.core.web.service.IBaseService; + +public interface LibraryProductImageService extends IBaseService { } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductService.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductService.java index 8b06c877..27dc4be0 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/LibraryProductService.java @@ -38,4 +38,7 @@ public interface LibraryProductService extends IBaseService { Page findLibraryProductPage(Integer pageNum, Integer pageSize); CommonResult updateBatchLibraryProductDTO(List products); + + + CommonResult shopImportToLib(Integer storeId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java index a250f78f..4f3b7acc 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java @@ -1,15 +1,9 @@ -/* - * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ package com.suisung.mall.shop.library.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.suisung.mall.common.feignService.AccountService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -18,25 +12,44 @@ import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.domain.UserDto; import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.library.LibraryProduct; +import com.suisung.mall.common.modules.library.LibraryProductImage; +import com.suisung.mall.common.modules.product.ShopProductBase; +import com.suisung.mall.common.modules.product.ShopProductImage; import com.suisung.mall.common.pojo.dto.LibraryProductDTO; import com.suisung.mall.common.utils.ContextUtil; +import com.suisung.mall.common.utils.FilePathUtils; import com.suisung.mall.core.consts.ConstantRedis; import com.suisung.mall.core.web.service.RedisService; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.library.mapper.LibraryProductMapper; +import com.suisung.mall.shop.library.service.LibraryProductImageService; import com.suisung.mall.shop.library.service.LibraryProductService; +import com.suisung.mall.shop.number.service.ShopNumberSeqService; +import com.suisung.mall.shop.page.service.OssService; +import com.suisung.mall.shop.product.service.ShopProductBaseService; +import com.suisung.mall.shop.product.service.ShopProductImageService; +import com.suisung.mall.shop.sixun.utils.CommonUtil; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Collectors; @Service +@Slf4j +@Transactional public class LibraryProductImpl extends BaseServiceImpl implements LibraryProductService { @Resource @@ -49,6 +62,29 @@ public class LibraryProductImpl extends BaseServiceImpl page= this.lists(queryWrapper,pageNum, pageSize); List libraryProductList= page.getRecords(); + + List libraryProductIds= libraryProductList.stream().map(LibraryProduct::getId).collect(Collectors.toList()); + QueryWrapper queryWrapperImage = new QueryWrapper<>(); + queryWrapperImage.in("product_id", libraryProductIds); + List libraryProductImageList= libraryProductImageService.list(queryWrapperImage); + + Map> listMap=new HashMap<>(); + libraryProductImageList.forEach(libraryProductImage -> { + libraryProductImage.setImageUrl(staticDomain+libraryProductImage.getImageUrl()); + List productImageList=listMap.get(libraryProductImage.getProductId()); + if(null==productImageList){ + productImageList=new ArrayList<>(); + } + productImageList.add(libraryProductImage); + listMap.put(libraryProductImage.getProductId(),productImageList); + }); + libraryProductList.forEach(libraryProduct->{ libraryProduct.setThumb(staticDomain+libraryProduct.getThumb()); + if(null==listMap.get(libraryProduct.getId())){ + libraryProduct.setProduct_image_list(Collections.emptyList()); + }else { + libraryProduct.setProduct_image_list(listMap.get(libraryProduct.getId())); + } }); page.setRecords(libraryProductList); return page; @@ -131,6 +189,7 @@ public class LibraryProductImpl extends BaseServiceImpl updateTableIds=new ArrayList<>(); + List updateProductImageList=new ArrayList<>(); products.forEach(product->{ if (null==product.getId()){ throw new ApiException("id is null"); @@ -138,11 +197,26 @@ public class LibraryProductImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id", storeId); + queryWrapper.eq("product_state_id",1001); + long total= shopProductBaseService.count(queryWrapper); + if(total<0){ + return CommonResult.failed("暂无同步数据"); + } + int pages= CommonUtil.getPagesCount((int) total,limitSize); + ExecutorService executor = Executors.newFixedThreadPool(6); + List> futures = new ArrayList<>(); + for (int i=1;i<=pages;i++){ + List shopProductBaseList= shopProductBaseService.lists(queryWrapper,i,limitSize).getRecords(); + QueryWrapper queryWrapper1 = new QueryWrapper<>(); + Map shopProductBaseMap=new HashMap<>(); + shopProductBaseList.forEach(m->{ + shopProductBaseMap.put(m.getProduct_id(),m); + }); + List productIds = shopProductBaseList.stream().map(ShopProductBase::getProduct_id).collect(Collectors.toList()); + queryWrapper1.in("product_id",productIds); + List shopProductImageList=shopProductImageService.list(queryWrapper1); + int finalI=i; + futures.add(executor.submit(() -> { + saveBatchLib(shopProductImageList,shopProductBaseMap); + return "成功" + finalI; + })); + } + // 等待所有任务完成 + for (Future future : futures) { + try { + log.info("同步图库任务结果: {}", future.get()); + } catch (Exception e) { + log.info("同步图库任务执行异常: {}", e.getMessage()); + } + } + executor.shutdown(); + copyToLib();//异步执行复制 + return CommonResult.success("导入成功:路径复制中..."); + } + /** + * 批量保存到图库 + * @param shopProductImageList + * @param shopProductBaseMap + */ + public void saveBatchLib(List shopProductImageList,Map shopProductBaseMap){ + TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); + transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); + transactionTemplate.setTimeout(60); // 60秒超时 + transactionTemplate.execute(status->{ + try { + List addLibraryProductList=new ArrayList<>(); + List addLibraryProductImageList=new ArrayList<>(); + Map existMap=checkedIsExist(shopProductBaseMap); + List filterShopProductImages = filterExistLibrary(shopProductImageList,shopProductBaseMap,existMap); + // redis获取id + List libraryIds= shopNumberSeqService.getBatchLibraryProductId(filterShopProductImages.size()); + for(int i=0;i queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status",2); + long total=libraryProductImageService.count(queryWrapper); + if(total<0){ + log.info("暂无同步数据"); + return; + } + Integer pages = CommonUtil.getPagesCount((int) total,limitSize); + ExecutorService executor = Executors.newFixedThreadPool(6); + List> futures = new ArrayList<>(); + for (int i=1;i<=pages;i++){ + int finalI=i; + List libraryProductImageList= libraryProductImageService.lists(queryWrapper,i,limitSize).getRecords(); + futures.add(executor.submit(() -> { + cosCopyUrl(libraryProductImageList); + return "成功:"+finalI; + })); + } + for (Future future : futures) { + try { + log.info("商品从店铺复制到图库成功:{}", future.get()); + } catch (Exception e) { + log.info("商品从店铺复制到图库执行异常:{}", e.getMessage()); + } + } + } + + /** + * cos的文件复制 + * @param libraryProductImageList + */ + public void cosCopyUrl(List libraryProductImageList){ +// TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); +// transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); +// transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); +// transactionTemplate.setTimeout(60); // 60秒超时 +// transactionTemplate.execute(status->{ + try { + + List updateLibraryProductList=new ArrayList<>(); + List updateLibraryProductImagetList=new ArrayList<>(); + for(LibraryProductImage libraryProductImage:libraryProductImageList){ + //文件复制 + FilePathUtils.FilePath filePath=new FilePathUtils().splitPathWithString(libraryProductImage.getImageUrl()); + String ossTargetUrl=LIBRARY_PATH+ DateUtil.format(libraryProductImage.getCreatedAt(),"yyyyMMdd")+"/"+filePath.getFilename(); + boolean result=ossService.copyFileUrl(filePath.getPath()+filePath.getFilename(),ossTargetUrl); + if (result){ + LibraryProduct libraryProduct=new LibraryProduct(); + libraryProduct.setId(libraryProductImage.getProductId()); + libraryProduct.setThumb(ossTargetUrl); + libraryProduct.setStatus(1); + updateLibraryProductList.add(libraryProduct); + + libraryProductImage.setProductId(libraryProduct.getId()); + libraryProductImage.setStatus(1); + libraryProductImage.setImageUrl(ossTargetUrl); + updateLibraryProductImagetList.add(libraryProductImage); + } + } + + if(!updateLibraryProductList.isEmpty()){//更新主图路径 + this.updateBatchById(updateLibraryProductList,updateLibraryProductList.size()); + } + if(!updateLibraryProductImagetList.isEmpty()){//更新副图路径 + libraryProductImageService.updateBatchById(updateLibraryProductImagetList,updateLibraryProductImagetList.size()); + } + + //return "成功"; + }catch (Exception e){ + // status.setRollbackOnly(); + log.info("处理数据异常:{}",e.getMessage()); + //return "失败"; + } + //}); + + } + + /** + * 校验是否存在,存在则去除 + * @param shopProductBaseMap + * @return + */ + private Map checkedIsExist(Map shopProductBaseMap){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + shopProductBaseMap.forEach((k,shopProductBase)->{ + if(StringUtils.isNotEmpty(shopProductBase.getProduct_number()) + && StringUtils.isNotEmpty(shopProductBase.getProduct_name())){ + queryWrapper.or(q->q.eq("barcode", shopProductBase.getProduct_number()). + eq("name",shopProductBase.getProduct_name())); + } + if (StringUtils.isEmpty(shopProductBase.getProduct_number())) { + queryWrapper.or(q->q.eq("name", shopProductBase.getProduct_name())); + } + }); + Map resultMap=new HashMap<>(); + List libraryProducts= this.list(queryWrapper); + for(LibraryProduct libraryProduct:libraryProducts){ + resultMap.put(libraryProduct.getBarcode()+"_"+libraryProduct.getName(),libraryProduct.getName()); + } + return resultMap; + } + + /** + * 去除存在的图片 + * @param shopProductImageList + * @param shopProductBaseMap + * @param existMap + * @return + */ + private List filterExistLibrary(List shopProductImageList,Map shopProductBaseMap, Map existMap){ + Iterator iterator = shopProductImageList.iterator(); + while(iterator.hasNext()){ + ShopProductImage shopProductImage = iterator.next(); + ShopProductBase shopProductBase=shopProductBaseMap.get(shopProductImage.getProduct_id()); + String key=shopProductBase.getProduct_number()+"_"+shopProductBase.getProduct_name(); + if(existMap.containsKey(key)){//存在则去除 + iterator.remove(); + } + } + return shopProductImageList; + } + + /** + * 清除缓存数据 + */ + private void clearCacheData(){ + Set item_keys = redisService.keys(ConstantRedis.Cache_NameSpace +"library_product_image"+ "*"); + redisService.del(item_keys); + Set base_keys = redisService.keys(ConstantRedis.Cache_NameSpace +"library_product"+ "*"); + redisService.del(base_keys); + } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java index 0cc7096d..440fa94d 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java @@ -176,10 +176,30 @@ public class ShopPageAppController extends BaseControllerImpl { data.put("items", items); data.put("current_tpl", current_tpl); - return CommonResult.success(data); } + @ApiOperation(value = "获取空白的编辑app模版", notes = "获取空白的编辑app模版") + @RequestMapping(value = "/getBlankTpl", method = RequestMethod.GET) + public CommonResult getBlankTpl() { + UserDto user = ContextUtil.getCurrentUser(); + if (user == null) { + throw new ApiUserException(I18nUtil._("用户信息异常!")); + } + Map blankTpl = new HashMap(); + blankTpl.put("tpl_id",107); + blankTpl.put("tpl_label","shop7"); + blankTpl.put("tpl_cat_name",""); + blankTpl.put("tpl_name","DIY模板"); + blankTpl.put("user_id",0); + blankTpl.put("tpl_buildin",0); + blankTpl.put("tpl_type",3); + blankTpl.put("tpl_image","https:\\/\\/static.shopsuite.cn\\/xcxfile\\/preview\\/diy.png"); + blankTpl.put("app_id",0); + blankTpl.put("id",107); + return CommonResult.success(blankTpl); + } + @ApiOperation(value = "店铺风格表-编辑app模版", notes = "店铺风格表-编辑app模版") @RequestMapping(value = "/editApp", method = RequestMethod.GET) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java index d94ca7e2..e162b3ba 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java @@ -73,4 +73,5 @@ public interface OssService { */ COSObjectSummary findNewestFile(String folder); + boolean copyFileUrl(String s, String ossTargetUrl); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java index dbba7329..68742a41 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java @@ -666,4 +666,32 @@ public class OssServiceImpl implements OssService { return localFolder; } + /** + * cos文件复制 + * @param ossSourcUrl + * @param ossTargetUrl + * @return + */ + public boolean copyFileUrl(String ossSourcUrl, String ossTargetUrl) { + int i=3; + while (i>0) { + try { + i--; + COSClient ossCli = initCOSClient(); + CopyObjectRequest copyObjectRequest = new CopyObjectRequest( + TENGXUN_BUCKET_NAME, ossSourcUrl, TENGXUN_BUCKET_NAME, ossTargetUrl); + CopyObjectResult result = ossCli.copyObject(copyObjectRequest); + return true; + //logger.info("文件复制成功:{}",ossTargetUrl); + //logger.info("result:{}",result); + }catch (Exception e){ + if(i==0){ + logger.error("腾讯云复制出错:{}",e.getMessage()); + return false; + } + } + } + return true; + } + } \ No newline at end of file diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java index 25ea1adb..b276f4fe 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java @@ -28,4 +28,6 @@ public class RedisKey { public static final String STOREDATALIBRARYID="storedata:libraryId"; public static final String STOREDATAGOODBATCHLOCK="store:data:goodsbatchLock"; + + public static final String STOREDATASHOPBASEPAGE="storedata:ShopBasePage"; } diff --git a/sql/shop/dev/20251122_dml.sql b/sql/shop/dev/20251122_dml.sql new file mode 100644 index 00000000..02b9e498 --- /dev/null +++ b/sql/shop/dev/20251122_dml.sql @@ -0,0 +1 @@ +alter table store_db_config add client_version char(10) NOT NULL DEFAULT '1' COMMENT '客户端版本:1商云10,2商瑞9.7,3商祺'; \ No newline at end of file diff --git a/sql/shop/dev/20251124_ddl.sql b/sql/shop/dev/20251124_ddl.sql new file mode 100644 index 00000000..fe3a6da7 --- /dev/null +++ b/sql/shop/dev/20251124_ddl.sql @@ -0,0 +1,3 @@ +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/getBlankTpl', 'index', 'master', '', '0', '/admin/shop/shop-page-app/getBlankTpl','dy空白模板'); +update shop_page_app set app_market_images='[]'; +alter table shop_page_app modify column app_market_images json COMMENT '市场展示图片'; \ No newline at end of file From c14cdb0967323838303a1752359b101463ae0c39 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Mon, 24 Nov 2025 17:40:17 +0800 Subject: [PATCH 31/81] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/suisung/mall/common/modules/page/ShopPageApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java index ff97f6ec..8ed2f193 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java @@ -80,6 +80,6 @@ public class ShopPageApp implements Serializable { @TableField(exist = false) private String tpl_label; - @ApiModelProperty(value = "市场展示图片,[{'imageUrl:'','content':''},{}]") + @ApiModelProperty(value = "市场展示图片,[{'imageUrl:'','description':''}") private String app_market_images; } From f06a1666939844a0c4dbe1a31fa3777bbb3aefc3 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Mon, 24 Nov 2025 18:02:21 +0800 Subject: [PATCH 32/81] =?UTF-8?q?redis=20key=20=E5=86=B2=E7=AA=81=EF=BC=8C?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/listener/OrderPayedListener.java | 26 +++++++------------ .../mall/shop/sync/keymanage/RedisKey.java | 23 +++++++++------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java index bc45b8ad..f876215d 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java @@ -115,28 +115,20 @@ public class OrderPayedListener { // 检查订单是否已经处理过(幂等性检查) if (isOrderPaid(orderInfoOld)) { - logger.info("[订单支付监听] 订单已支付,无需重复处理,订单ID: {}", orderId); + logger.debug("[订单支付监听] 订单已支付,无需重复处理,订单ID: {}", orderId); flag = true; continue; } - if (order_state_id == StateCode.ORDER_STATE_WAIT_PAY) { - // 待支付状态 - logger.info("[订单支付监听] 处理待支付订单. 订单ID: {}", orderId); - flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId)); + if (StateCode.PAYMENT_TYPE_OFFLINE == orderInfoOld.getPayment_type_id().intValue()) { + logger.debug("[订单支付监听] 处理线下支付订单. 订单ID: {}", orderId); + ShopOrderInfo orderInfo = new ShopOrderInfo(); + orderInfo.setOrder_id(orderId); + orderInfo.setOrder_is_paid(StateCode.ORDER_PAID_STATE_YES); + flag = shopOrderInfoService.edit(orderInfo); } else { - //判断是否线下支付 - if (StateCode.PAYMENT_TYPE_OFFLINE == orderInfoOld.getPayment_type_id().intValue()) { - //线下支付,直接处理订单支付状态, 不处理订单状态 - logger.info("[订单支付监听] 处理线下支付订单. 订单ID: {}", orderId); - ShopOrderInfo orderInfo = new ShopOrderInfo(); - orderInfo.setOrder_id(orderId); - orderInfo.setOrder_is_paid(StateCode.ORDER_PAID_STATE_YES); - flag = shopOrderInfoService.edit(orderInfo); - } else { - logger.info("[订单支付监听] 处理其他支付订单. 订单ID: {}", orderId); - flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId)); - } + logger.debug("[订单支付监听] 处理支付订单. 订单ID: {}", orderId); + flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId)); } logger.info("[订单支付监听] 订单ID: {},支付异步通知回调处理是否成功: {} ", flag, orderId); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java index 25ea1adb..2b13b698 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/keymanage/RedisKey.java @@ -4,28 +4,31 @@ public class RedisKey { //public static final String SXCLIENTKEYVERSION="sxclientKey:version";//客户端版本 - public static final String STOREDATARELEASE="shopQuality:release"; + public static final String STOREDATARELEASE = "shopQuality:release"; - public static final String STOREDATAPRODUCTMAPING="storedata:productMaping"; + public static final String STOREDATAPRODUCTMAPING = "storedata:productMaping"; - public static final String STOREDATASHOPBASEPRODUCTSPEC="storedata:shopBaseProductSpec"; + public static final String STOREDATASHOPBASEPRODUCTSPEC = "storedata:shopBaseProductSpec"; - public static final String STOREDATASPECITEMID="storedata:SpecItemId"; + public static final String STOREDATASPECITEMID = "storedata:SpecItemId"; - public static final String STOREDATAPRODUCTSPECITEM="storedata:ProductSpecItem"; + public static final String STOREDATAPRODUCTSPECITEM = "storedata:ProductSpecItem"; - public static final String STOREDBDATAPRIORITYMODEKEY="storedbdata:priorityModeKey"; + public static final String STOREDBDATAPRIORITYMODEKEY = "storedbdata:priorityModeKey"; - public static final String STOREDATACCOUNTBASEID="storedata:accountBaseId"; + public static final String STOREDATACCOUNTBASEID = "storedata:accountBaseId"; - public static final String STOREDATASPECID="storedata:SpecId"; + public static final String STOREDATASPECID = "storedata:SpecId"; - public static final String STOREDATALIBRARYID="storedata:libraryId"; + public static final String STOREDATALIBRARYID = "storedata:libraryId"; - public static final String STOREDATAGOODBATCHLOCK="store:data:goodsbatchLock"; + public static final String STOREDATAGOODBATCHLOCK = "store:data:goodsbatchLock"; + + + public static final String STOREDATASHOPBASEPAGE = "store:data:shop:base:page"; } From d2c9b6c492f99b68884b880f600b7391f9308d6f Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Mon, 24 Nov 2025 18:08:21 +0800 Subject: [PATCH 33/81] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/utils/FilePathUtils.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 mall-common/src/main/java/com/suisung/mall/common/utils/FilePathUtils.java diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/FilePathUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/FilePathUtils.java new file mode 100644 index 00000000..aee26a17 --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/FilePathUtils.java @@ -0,0 +1,47 @@ +package com.suisung.mall.common.utils; + +import lombok.Data; + +public class FilePathUtils { + /** + * 使用lastIndexOf分割路径和文件名 + */ + public FilePath splitPathWithString(String fileUrl) { + // 去除域名 + String noDomain = fileUrl.replaceFirst("^https?://[^/]+/", ""); + + // 分割路径和文件名 + int lastSlash = noDomain.lastIndexOf('/'); + String path, filename; + + if (lastSlash != -1) { + path = noDomain.substring(0, lastSlash + 1); + filename = noDomain.substring(lastSlash + 1); + } else { + path = ""; + filename = noDomain; + } + FilePath filePath=new FilePath(); + filePath.path=path; + filePath.filename=filename; + return filePath; +// System.out.println("原始URL: " + fileUrl); +// System.out.println("去除域名: " + noDomain); +// System.out.println("文件路径: " + path); +// System.out.println("文件名称: " + filename); + } + @Data + public class FilePath{ + private String path;//路径,不包含文件名称如media/media/plantform/20250906/ + private String filename;//文件名称 + + } + public static void main(String[] args) { + String cosUrl = "https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/media/media/plantform/20250906/b93a9751b35a49fca6cf979829230868.png"; + + // 方法1:基础分割 + FilePath filePath= new FilePathUtils().splitPathWithString(cosUrl); + System.out.println("文件路径: " + filePath.getPath()); + System.out.println("文件名称: " + filePath.getFilename()); + } +} From 06df245d59598e97d86eaefe55e287a5c0c5ca1f Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Tue, 25 Nov 2025 11:26:01 +0800 Subject: [PATCH 34/81] =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=8A=9F=E8=83=BD=EF=BC=8C=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=BA=97=E9=93=BA=E7=9A=84=E6=A8=A1=E6=9D=BF=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/ShopPageAppController.java | 22 +++++-- .../shop/page/service/ShopPageAppService.java | 2 + .../service/impl/ShopPageAppServiceImpl.java | 63 +++++++++++++++++-- sql/shop/dev/20251125_ddl.sql | 1 + 4 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 sql/shop/dev/20251125_ddl.sql diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java index 440fa94d..f52f7ea9 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java @@ -110,21 +110,23 @@ public class ShopPageAppController extends BaseControllerImpl { Map current_tpl = new HashMap(); Iterator it = items.iterator(); + //读取店铺信息store_template + ShopStoreInfo shopStoreInfo = shopStoreInfoService.get(user.getStore_id()); while (it.hasNext()) { Map item = it.next(); Integer tpl_id = Convert.toInt(item.get("tpl_id")); String tpl_label =CommonUtil.getTplLable(tpl_id); //String tpl_label = item.get("tpl_label").toString(); item.put("tpl_label",tpl_label); + Integer is_use=Convert.toInt(item.get("app_is_use"),0); if (user.isStore()) { - //读取店铺信息store_template - ShopStoreInfo shopStoreInfo = shopStoreInfoService.get(user.getStore_id()); if (tpl_id > 1000 || tpl_id == 109 || tpl_id == 105 || tpl_id == 10/* || tpl_id == 107*/) { it.remove(); continue; } - String appId= String.valueOf(item.get("app_id")); - if (shopStoreInfo.getStore_template().equals(appId)) { + //String appId= String.valueOf(item.get("tpl_label")); + if (is_use==1&&(shopStoreInfo.getStore_template().equals(tpl_label)|| + shopStoreInfo.getStore_template().equals(String.valueOf(item.get("tpl_label"))))) { current_tpl = item; } } else { @@ -526,5 +528,17 @@ public class ShopPageAppController extends BaseControllerImpl { return CommonResult.success(); } + + /** + * 市场app删除 + * @param appId + * @return + */ + @ApiOperation(value = "店铺风格表-市场app删除", notes = "店铺风格表-市场app删除") + @RequestMapping(value = "/deletePageApp", method = RequestMethod.DELETE) + public CommonResult deletePageApp(Integer appId) { + return shopPageAppService.deletePageApp(appId); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java index 6cba0730..ff367287 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java @@ -58,4 +58,6 @@ public interface ShopPageAppService extends IBaseService { CommonResult copyDiyByStore(Integer sourceStoreId, Integer tpl_id); CommonResult copyDiyByAppId(Integer appId,String a); + + CommonResult deletePageApp(Integer appId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java index f091b627..4141e94a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java @@ -24,6 +24,7 @@ import com.suisung.mall.common.modules.store.ShopStoreInfo; import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.common.utils.ContextUtil; import com.suisung.mall.common.utils.I18nUtil; +import com.suisung.mall.common.utils.StringUtils; import com.suisung.mall.core.web.service.CloundService; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.base.service.AccountBaseConfigService; @@ -35,14 +36,12 @@ import com.suisung.mall.shop.page.service.ShopPageAppService; import com.suisung.mall.shop.page.service.ShopPageBaseService; import com.suisung.mall.shop.page.service.ShopPageModuleService; import com.suisung.mall.shop.product.service.ShopPageUserFormService; -import com.suisung.mall.shop.product.service.impl.ShopPageUserFormServiceImpl; import com.suisung.mall.shop.store.service.ShopStoreInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.servlet.ModelAndView; -import javax.security.sasl.AuthenticationException; import javax.servlet.http.Cookie; import java.util.*; import java.util.stream.Collectors; @@ -415,19 +414,36 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); UserDto user = getCurrentUser(); - if (user.isStore()) { + String app_idStr=getParameter("app_id"); + if(StringUtils.isNotEmpty(app_idStr)){ + Integer app_id=Convert.toInt(app_idStr); + ShopPageApp shopPageApp= this.get(app_id); + if(null!=shopPageApp){ + queryWrapper.eq("store_id", shopPageApp.getStore_id()); + queryWrapper.eq("app_is_use", 1); + List updateShopPageApps= this.list(queryWrapper); + if(!updateShopPageApps.isEmpty()){ + updateShopPageApps=updateShopPageApps.stream().peek(s->s.setApp_is_use(0)).collect(Collectors.toList()); + this.updateBatchById(updateShopPageApps,updateShopPageApps.size()); + } + shopPageApp.setApp_is_use(1); + this.updateById(shopPageApp); + } + } queryWrapper.eq("store_id", Convert.toInt(user.getStore_id())); ShopStoreInfo shopStoreInfo = new ShopStoreInfo(); shopStoreInfo.setStore_id(Convert.toInt(user.getStore_id())); //shopStoreInfo.setStore_template(getParameter("store_template", "shop1")); - shopStoreInfo.setStore_template(String.valueOf(getParameter("app_id", 0))); + String store_template="shop7"; + if(null!=getParameter("store_template")){ + store_template=String.valueOf(getParameter("store_template")); + } + shopStoreInfo.setStore_template(store_template); shopStoreInfoService.edit(shopStoreInfo); } else { queryWrapper.eq("store_id", 0); - - Integer subsiteId = accountBaseConfigService.getSubsiteId(); if (CheckUtil.isEmpty(subsiteId)) { AccountBaseConfig config = new AccountBaseConfig(); @@ -601,6 +617,7 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl queryWrapperShopBase = new QueryWrapper<>(); + queryWrapperShopBase.eq("app_id", appId); + List shopPageBases= shopPageBaseService.list(queryWrapperShopBase); + if(!shopPageBases.isEmpty()){ + List shopPageIdList= shopPageBases.stream().map(ShopPageBase::getPage_id).collect(Collectors.toList()); + QueryWrapper queryWrapperShopPageModule = new QueryWrapper<>(); + queryWrapperShopPageModule.in("page_id", shopPageIdList); + shopPageModuleService.remove(queryWrapperShopPageModule); + QueryWrapper queryWrapperShopPageUserForm = new QueryWrapper<>(); + queryWrapperShopPageUserForm.in("page_id", shopPageIdList); + shopPageUserFormService.remove(queryWrapperShopPageUserForm); + shopPageBaseService.removeBatchByIds(shopPageIdList); + } + shopPageAppService.remove(shopPageApp.getApp_id()); + return CommonResult.success(); + } + /** * 生产新的id diff --git a/sql/shop/dev/20251125_ddl.sql b/sql/shop/dev/20251125_ddl.sql new file mode 100644 index 00000000..0476bcc9 --- /dev/null +++ b/sql/shop/dev/20251125_ddl.sql @@ -0,0 +1 @@ +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-page-app/deletePageApp', 'index', 'master', '', '0', '/admin/shop/shop-page-app/deletePageApp','dy模板删除'); \ No newline at end of file From d8aadb2d4779ccebd040839f05bb7d1bc3571040 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Tue, 25 Nov 2025 16:23:27 +0800 Subject: [PATCH 35/81] =?UTF-8?q?=E6=96=B0=E5=BA=97=E9=93=BA=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/ShopPageAppController.java | 13 ++++++++++--- .../page/service/impl/ShopPageAppServiceImpl.java | 11 +++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java index f52f7ea9..db728f64 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java @@ -77,6 +77,7 @@ public class ShopPageAppController extends BaseControllerImpl { Map data_arr = null; JSONArray items_arr =null; List items =null; + boolean isNewFlag=false; try { // data_arr = cloundService.getAppTpl(accountBaseConfigService.getConfig("service_user_id", 0), accountBaseConfigService.getConfig("service_app_key", ""), null); if(user.isStore()) { @@ -89,6 +90,7 @@ public class ShopPageAppController extends BaseControllerImpl { data_arr = (Map)jsonObject.get("data"); items_arr = (JSONArray) data_arr.get("items"); items = JSONUtil.toList(items_arr, Map.class); + isNewFlag=true; }else { Gson gson = new Gson(); String gsonStrList= gson.toJson(shopPageAppList); @@ -125,9 +127,12 @@ public class ShopPageAppController extends BaseControllerImpl { continue; } //String appId= String.valueOf(item.get("tpl_label")); - if (is_use==1&&(shopStoreInfo.getStore_template().equals(tpl_label)|| - shopStoreInfo.getStore_template().equals(String.valueOf(item.get("tpl_label"))))) { + if(isNewFlag&&shopStoreInfo.getStore_template().equals(String.valueOf(item.get("tpl_label")))){ current_tpl = item; + }else { + if (is_use==1&&(shopStoreInfo.getStore_template().equals(tpl_label))) { + current_tpl = item; + } } } else { @@ -175,7 +180,9 @@ public class ShopPageAppController extends BaseControllerImpl { queryWrapper.eq("store_id", 0); } */ - + if(isNewFlag){ + items=new ArrayList<>(); + } data.put("items", items); data.put("current_tpl", current_tpl); return CommonResult.success(data); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java index 4141e94a..89ecc618 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java @@ -665,7 +665,10 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl Date: Tue, 25 Nov 2025 16:26:45 +0800 Subject: [PATCH 36/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=95=86=E5=93=81=E5=90=8D=E7=A7=B0=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/service/impl/ShopProductBaseServiceImpl.java | 6 +++--- .../shop/sync/service/impl/SyncBaseThirdSxAbstract.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java index 655d46af..4c307b9d 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java @@ -5398,14 +5398,14 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl Date: Tue, 25 Nov 2025 16:36:58 +0800 Subject: [PATCH 37/81] =?UTF-8?q?=E5=92=A8=E8=AF=A2=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=92=8C=E5=BA=97=E9=93=BA=20api=20=E6=8E=A5=E5=8F=A3=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E7=99=BD=E5=90=8D=E5=8D=95=EF=BC=8C=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=99=BB=E5=BD=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 2 + .../service/impl/SnsStoryBaseServiceImpl.java | 202 ++++++++++++------ .../impl/SnsStoryCategoryServiceImpl.java | 178 ++++++++++----- 3 files changed, 263 insertions(+), 119 deletions(-) diff --git a/mall-gateway/src/main/resources/application.yml b/mall-gateway/src/main/resources/application.yml index ab1ee4e9..e0a0fbcb 100644 --- a/mall-gateway/src/main/resources/application.yml +++ b/mall-gateway/src/main/resources/application.yml @@ -93,6 +93,8 @@ secure: - "/mobile/shop/lakala/sign/ec/**" - "/mobile/**/**/test/case" - "/**/**/testcase" + - "/mobile/sns/Story/listComment" + - "/mobile/sns/Story/getStory" universal: urls: - "/admin/account/account-user-base/info" diff --git a/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryBaseServiceImpl.java b/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryBaseServiceImpl.java index 35ac0cbb..40b707fb 100644 --- a/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryBaseServiceImpl.java +++ b/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryBaseServiceImpl.java @@ -185,7 +185,7 @@ public class SnsStoryBaseServiceImpl extends BaseServiceImpl column_row = new QueryWrapper<>(); //查询获得相关的SnsStoryBase列表集合 if (storySearchDTO.getStory_type() != null) { @@ -266,44 +266,44 @@ public class SnsStoryBaseServiceImpl extends BaseServiceImpl queryWrapper=new QueryWrapper<>(); - queryWrapper.eq("user_id",user.getId()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id", user.getId()); List snsStoryLikes = snsStoryLikeService.find(queryWrapper); List collect = snsStoryLikes.stream().map(s -> s.getStory_id()).distinct().collect(Collectors.toList()); - for(Map item :items){ + for (Map item : items) { Integer story_id = Convert.toInt(item.get("story_id")); - if(collect.contains(story_id)){ - item.put("IsFabulous",1); - }else{ - item.put("IsFabulous",0); + if (collect.contains(story_id)) { + item.put("IsFabulous", 1); + } else { + item.put("IsFabulous", 0); } } //用户是否收藏 - QueryWrapper snsStoryCollectionQueryWrapper=new QueryWrapper<>(); - snsStoryCollectionQueryWrapper.eq("user_id",user.getId()); + QueryWrapper snsStoryCollectionQueryWrapper = new QueryWrapper<>(); + snsStoryCollectionQueryWrapper.eq("user_id", user.getId()); List snsStoryCollections = snsStoryCollectionService.find(snsStoryCollectionQueryWrapper); List collectionList = snsStoryCollections.stream().map(s -> s.getStory_id()).distinct().collect(Collectors.toList()); - for(Map item :items){ + for (Map item : items) { Integer story_id = Convert.toInt(item.get("story_id")); - if(collectionList.contains(story_id)){ - item.put("IsCollection",1); - }else{ - item.put("IsCollection",0); + if (collectionList.contains(story_id)) { + item.put("IsCollection", 1); + } else { + item.put("IsCollection", 0); } } //用户是否关注 - for(Map item:items){ - QueryWrapper friendQueryWrapper=new QueryWrapper<>(); - friendQueryWrapper.eq("user_id",user.getId()).eq("friend_id",Convert.toInt(item.get("user_id"))); + for (Map item : items) { + QueryWrapper friendQueryWrapper = new QueryWrapper<>(); + friendQueryWrapper.eq("user_id", user.getId()).eq("friend_id", Convert.toInt(item.get("user_id"))); SnsUserFriend one = snsUserFriendService.findOne(friendQueryWrapper); - if(one!=null){ - item.put("IsFollow",true); - }else{ - item.put("IsFollow",false); + if (one != null) { + item.put("IsFollow", true); + } else { + item.put("IsFollow", false); } } } @@ -382,7 +382,7 @@ public class SnsStoryBaseServiceImpl extends BaseServiceImpl item_ids = Convert.toList(Long.class, str_item_id); - Map product_row = shopService.getProductItemOne(item_ids.get(0)); + try { + List item_ids = Convert.toList(Long.class, str_item_id); + // 检查列表是否为空以及索引是否有效 + if (CollUtil.isNotEmpty(item_ids) && item_ids.get(0) != null) { + Map product_row = shopService.getProductItemOne(item_ids.get(0)); - if (CollUtil.isNotEmpty(product_row)) { - String product_name = Convert.toStr(product_row.get("product_name"), ""); - String item_name = Convert.toStr(product_row.get("item_name"), ""); - row.put("product_item_name", product_name + " " + item_name); - row.put("item_unit_price", product_row.get("item_unit_price")); - row.put("item_market_price", product_row.get("item_market_price")); - row.put("product_image", product_row.get("product_image")); + if (CollUtil.isNotEmpty(product_row)) { + String product_name = Convert.toStr(product_row.get("product_name"), ""); + String item_name = Convert.toStr(product_row.get("item_name"), ""); + row.put("product_item_name", product_name + " " + item_name); + row.put("item_unit_price", product_row.get("item_unit_price")); + row.put("item_market_price", product_row.get("item_market_price")); + row.put("product_image", product_row.get("product_image")); + } + } + } catch (Exception e) { + log.warn("获取商品信息失败, story_id: {}, item_id: {}", story_id, str_item_id, e); + // 发生异常时保持默认值 } } - // 是否点赞 - QueryWrapper likeQueryWrapper = new QueryWrapper<>(); - likeQueryWrapper.eq("story_id", story_id).eq("user_id", user_id); - SnsStoryLike story_like_row = snsStoryLikeService.findOne(likeQueryWrapper); - row.put("IsFabulous", story_like_row != null ? 1 : 0); + // 是否点赞 - 只有登录用户才能查看点赞状态 + if (user_id != null) { + try { + QueryWrapper likeQueryWrapper = new QueryWrapper<>(); + likeQueryWrapper.eq("story_id", story_id).eq("user_id", user_id); + SnsStoryLike story_like_row = snsStoryLikeService.findOne(likeQueryWrapper); + row.put("IsFabulous", story_like_row != null ? 1 : 0); + } catch (Exception e) { + log.warn("查询点赞状态失败, story_id: {}, user_id: {}", story_id, user_id, e); + row.put("IsFabulous", 0); + } + } else { + row.put("IsFabulous", 0); // 未登录用户默认未点赞 + } // 下面两个查询用不到 - /*QueryWrapper advertisementQueryWrapper = new QueryWrapper<>(); - advertisementQueryWrapper.eq("adv_enable", 1).eq("adv_is_top", 1); - row.put("adv_top", snsStoryAdvertisementService.findOne(advertisementQueryWrapper)); + /*QueryWrapper advertisementQueryWrapper = new QueryWrapper<>(); + advertisementQueryWrapper.eq("adv_enable", 1).eq("adv_is_top", 1); + row.put("adv_top", snsStoryAdvertisementService.findOne(advertisementQueryWrapper)); - QueryWrapper advListQueryWrapper = new QueryWrapper<>(); - advListQueryWrapper.eq("adv_enable", 1).eq("adv_is_top", 0); - row.put("adv_lists", snsStoryAdvertisementService.find(advListQueryWrapper));*/ + QueryWrapper advListQueryWrapper = new QueryWrapper<>(); + advListQueryWrapper.eq("adv_enable", 1).eq("adv_is_top", 0); + row.put("adv_lists", snsStoryAdvertisementService.find(advListQueryWrapper));*/ // 移动端不需要分类 if (!isMobile()) { - row.put("category_row", snsStoryCategoryService.find(new QueryWrapper<>())); - QueryWrapper baseQueryWrapper = new QueryWrapper<>(); - baseQueryWrapper.eq("user_id", row.get("user_id")).eq("story_status", 1).eq("story_enable", 1).eq("story_privacy", 0).orderByDesc("story_time"); - row.put("story_user_items", snsStoryBaseService.lists(baseQueryWrapper, 1, 5).getRecords()); + try { + row.put("category_row", snsStoryCategoryService.find(new QueryWrapper<>())); + QueryWrapper baseQueryWrapper = new QueryWrapper<>(); + baseQueryWrapper.eq("user_id", row.get("user_id")) + .eq("story_status", 1) + .eq("story_enable", 1) + .eq("story_privacy", 0) + .orderByDesc("story_time"); + + Object userId = row.get("user_id"); + if (userId != null) { + Page storyPage = snsStoryBaseService.lists(baseQueryWrapper, 1, 5); + row.put("story_user_items", storyPage.getRecords()); + } else { + row.put("story_user_items", new ArrayList<>()); + } + } catch (Exception e) { + log.warn("获取用户故事列表失败, user_id: {}", row.get("user_id"), e); + row.put("story_user_items", new ArrayList<>()); + } } - QueryWrapper friendQueryWrapper = new QueryWrapper<>(); - friendQueryWrapper.eq("friend_id", row.get("user_id")).eq("user_id", user_id); - SnsUserFriend friend_row = snsUserFriendService.findOne(friendQueryWrapper); + // 关注状态 - 只有登录用户才能查看关注状态 + if (user_id != null && row.get("user_id") != null) { + try { + QueryWrapper friendQueryWrapper = new QueryWrapper<>(); + friendQueryWrapper.eq("friend_id", row.get("user_id")).eq("user_id", user_id); + SnsUserFriend friend_row = snsUserFriendService.findOne(friendQueryWrapper); - if (friend_row != null) { - row.put("IsFollow", 1); + if (friend_row != null) { + row.put("IsFollow", 1); + } else { + row.put("IsFollow", 0); + } + } catch (Exception e) { + log.warn("查询关注状态失败, friend_id: {}, user_id: {}", row.get("user_id"), user_id, e); + row.put("IsFollow", 0); + } } else { - row.put("IsFollow", 0); + row.put("IsFollow", 0); // 未登录用户默认未关注 } - //row.put("story_file", StrUtil.split(row.get("story_file").toString(), ",")); - row.put("story_file", Convert.toList(String.class, row.get("story_file"))); + // 处理故事文件 + try { + //row.put("story_file", StrUtil.split(row.get("story_file").toString(), ",")); + Object storyFileObj = row.get("story_file"); + if (storyFileObj != null) { + row.put("story_file", Convert.toList(String.class, storyFileObj)); + } else { + row.put("story_file", new ArrayList<>()); + } + } catch (Exception e) { + log.warn("处理故事文件失败, story_id: {}", story_id, e); + row.put("story_file", new ArrayList<>()); + } return row; } diff --git a/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryCategoryServiceImpl.java b/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryCategoryServiceImpl.java index b9e4292d..86336148 100644 --- a/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryCategoryServiceImpl.java +++ b/mall-sns/src/main/java/com/suisung/mall/sns/service/impl/SnsStoryCategoryServiceImpl.java @@ -189,99 +189,170 @@ public class SnsStoryCategoryServiceImpl extends BaseServiceImpl wrapper = new QueryWrapper<>(); Integer story_id = Convert.toInt(getParameter("story_id")); + + // 参数校验 + if (story_id == null || story_id <= 0) { + return new HashMap(); + } + wrapper.eq("story_id", story_id); wrapper.orderByDesc("comment_time"); - Map data = snsStoryCommentService.getLists(wrapper, page, rows); + + Map data = new HashMap(); + try { + data = snsStoryCommentService.getLists(wrapper, page, rows); + } catch (Exception e) { + // 处理查询异常 + data.put("items", new ArrayList<>()); + data.put("total", 0); + } + + // 确保 items 字段存在 + if (data.get("items") == null) { + data.put("items", new ArrayList<>()); + } + data.put("items", accountService.fixUserAvatar((List) data.get("items"), false)); //读取评论回复 List items = (List) data.get("items"); if (CollUtil.isEmpty(items)) { - return new HashMap(); + return data; } - List comment_id_row = items.stream().map(s -> Convert.toInt(s.get("comment_id"))).collect(Collectors.toList()); + // 避免转换中的空值问题 + List comment_id_row = items.stream() + .map(s -> Convert.toInt(s.get("comment_id"))) + .filter(id -> id != null) + .collect(Collectors.toList()); + + if (CollUtil.isEmpty(comment_id_row)) { + return data; + } QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.in("comment_id", comment_id_row); - queryWrapper.eq("user_id", user_id); - // + if (user_id != null) { + queryWrapper.eq("user_id", user_id); + } + //判断评论是否IsFabulous - List snsStoryCommentHelpfuls = snsStoryCommentHelpfulService.find(queryWrapper); + List snsStoryCommentHelpfuls = new ArrayList<>(); + try { + snsStoryCommentHelpfuls = snsStoryCommentHelpfulService.find(queryWrapper); + } catch (Exception e) { + // 忽略查询异常 + } + List comment_helpful_rows = Convert.toList(Map.class, snsStoryCommentHelpfuls); + if (comment_helpful_rows == null) { + comment_helpful_rows = new ArrayList<>(); + } QueryWrapper snsStoryCommentReplyQueryWrapper = new QueryWrapper<>(); snsStoryCommentReplyQueryWrapper.in("comment_id", comment_id_row); snsStoryCommentReplyQueryWrapper.eq("comment_reply_show_flag", 1); snsStoryCommentReplyQueryWrapper.orderByDesc("comment_reply_time"); - List snsStoryCommentReplies = snsStoryCommentReplyService.find(snsStoryCommentReplyQueryWrapper); - List comment_reply_rows = Convert.toList(Map.class, snsStoryCommentReplies); + List snsStoryCommentReplies = new ArrayList<>(); + try { + snsStoryCommentReplies = snsStoryCommentReplyService.find(snsStoryCommentReplyQueryWrapper); + } catch (Exception e) { + // 忽略查询异常 + } + + List comment_reply_rows = Convert.toList(Map.class, snsStoryCommentReplies); + if (comment_reply_rows == null) { + comment_reply_rows = new ArrayList<>(); + } + + try { + accountService.fixUserAvatar(comment_reply_rows, false); + } catch (Exception e) { + // 忽略头像修复异常 + } - accountService.fixUserAvatar(comment_reply_rows, false); Map comment_reply_tmp_rows = new HashMap(); for (Map comment_reply_row : comment_reply_rows) { Integer comment_id = Convert.toInt(comment_reply_row.get("comment_id")); + if (comment_id == null) continue; // 避免空值 + List comment_rows = (List) ObjectUtil.defaultIfNull(comment_reply_tmp_rows.get(comment_id), new ArrayList()); - if (CollUtil.isEmpty(comment_rows)) comment_reply_tmp_rows.put(comment_id, comment_rows); + if (CollUtil.isEmpty(comment_rows)) { + comment_reply_tmp_rows.put(comment_id, new ArrayList<>()); // 使用新实例 + comment_rows = (List) comment_reply_tmp_rows.get(comment_id); + } comment_rows.add(comment_reply_row); } //判断子评论是否IsFabulous - List comment_reply_id_row = comment_reply_rows.stream().map(s -> Convert - .toInt(s.get("comment_reply_id"))).collect(Collectors.toList()); + List comment_reply_id_row = comment_reply_rows.stream() + .map(s -> Convert.toInt(s.get("comment_reply_id"))) + .filter(id -> id != null) + .collect(Collectors.toList()); - QueryWrapper helpfulQueryWrapper = new QueryWrapper<>(); - if (CollUtil.isNotEmpty(comment_reply_id_row)) helpfulQueryWrapper.in("comment_reply_id", comment_reply_id_row); + Map comment_reply_helpful_tmp_rows = new HashMap(); // 提前定义变量 + if (CollUtil.isNotEmpty(comment_reply_id_row)) { + QueryWrapper helpfulQueryWrapper = new QueryWrapper<>(); + helpfulQueryWrapper.in("comment_reply_id", comment_reply_id_row); + if (user_id != null) { + helpfulQueryWrapper.eq("user_id", user_id); + } - helpfulQueryWrapper.eq("user_id", user_id); + List storyCommentHelpfuls = new ArrayList<>(); + try { + storyCommentHelpfuls = snsStoryCommentReplyHelpfulService.find(helpfulQueryWrapper); + } catch (Exception e) { + // 忽略查询异常 + } - List storyCommentHelpfuls = snsStoryCommentReplyHelpfulService.find(helpfulQueryWrapper); - List comment_reply_helpful_rows = Convert.toList(Map.class, storyCommentHelpfuls); + List comment_reply_helpful_rows = Convert.toList(Map.class, storyCommentHelpfuls); + if (comment_reply_helpful_rows == null) { + comment_reply_helpful_rows = new ArrayList<>(); + } - Map comment_reply_helpful_tmp_rows = new HashMap(); - for (Map comment_reply_helpful_row : comment_reply_helpful_rows) { - Integer comment_reply_id = Convert.toInt(comment_reply_helpful_row.get("comment_reply_id")); - List comment_rows = (List) ObjectUtil.defaultIfNull(comment_reply_helpful_tmp_rows.get(comment_reply_id), new ArrayList()); - if (CollUtil.isEmpty(comment_rows)) comment_reply_helpful_tmp_rows.put(comment_reply_id, comment_rows); - comment_rows.add(comment_reply_helpful_row); + for (Map comment_reply_helpful_row : comment_reply_helpful_rows) { + Integer comment_reply_id = Convert.toInt(comment_reply_helpful_row.get("comment_reply_id")); + if (comment_reply_id == null) continue; // 避免空值 + + List comment_rows = (List) ObjectUtil.defaultIfNull(comment_reply_helpful_tmp_rows.get(comment_reply_id), new ArrayList()); + if (CollUtil.isEmpty(comment_rows)) { + comment_reply_helpful_tmp_rows.put(comment_reply_id, new ArrayList<>()); // 使用新实例 + comment_rows = (List) comment_reply_helpful_tmp_rows.get(comment_reply_id); + } + comment_rows.add(comment_reply_helpful_row); + } } - /* - QueryWrapper wrapper1 = new QueryWrapper<>(); - wrapper1.in("comment_id", comment_id_row); - wrapper1.eq("user_id", user_id); - List storyCommentReplies = snsStoryCommentReplyService.find(wrapper1); - - */ - - comment_helpful_rows = Convert.toList(Map.class, snsStoryCommentHelpfuls); - Map comment_helpful_tmp_rows = new HashMap(); for (Map comment_helpful_row : comment_helpful_rows) { - Integer comment_id = Convert.toInt(comment_helpful_row.get("comment_id")); - List comment_rows = (List) ObjectUtil.defaultIfNull(comment_helpful_tmp_rows.get(comment_id), new ArrayList()); - if (CollUtil.isEmpty(comment_rows)) comment_reply_helpful_tmp_rows.put(comment_id, comment_rows); + if (comment_id == null) continue; // 避免空值 + List comment_rows = (List) ObjectUtil.defaultIfNull(comment_helpful_tmp_rows.get(comment_id), new ArrayList()); + if (CollUtil.isEmpty(comment_rows)) { + comment_helpful_tmp_rows.put(comment_id, new ArrayList<>()); // 使用新实例 + comment_rows = (List) comment_helpful_tmp_rows.get(comment_id); + } comment_rows.add(comment_helpful_row); - comment_helpful_tmp_rows.put(comment_helpful_row.get("comment_id"), comment_helpful_row); } for (Map item : items) { Integer comment_id = Convert.toInt(item.get("comment_id")); + if (comment_id == null) continue; // 避免空值 + if (ObjectUtil.isNotNull(comment_reply_tmp_rows.get(comment_id))) { item.put("commentList", comment_reply_tmp_rows.get(comment_id)); } else { @@ -292,22 +363,22 @@ public class SnsStoryCategoryServiceImpl extends BaseServiceImpl Date: Tue, 25 Nov 2025 17:07:32 +0800 Subject: [PATCH 38/81] =?UTF-8?q?=E5=9B=BE=E5=BA=93=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/shop/library/service/impl/LibraryProductImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java index 4f3b7acc..893ab8f8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java @@ -146,6 +146,10 @@ public class LibraryProductImpl extends BaseServiceImpl libraryProductList= page.getRecords(); + if (CollectionUtil.isEmpty(libraryProductList)) { + return page; + } + List libraryProductIds= libraryProductList.stream().map(LibraryProduct::getId).collect(Collectors.toList()); QueryWrapper queryWrapperImage = new QueryWrapper<>(); queryWrapperImage.in("product_id", libraryProductIds); From 71cef214726cb5aa310a95bea01664149b131a18 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Tue, 25 Nov 2025 17:17:06 +0800 Subject: [PATCH 39/81] =?UTF-8?q?=E5=9B=BE=E5=BA=93=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/shop/library/service/impl/LibraryProductImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java index 893ab8f8..ff746a06 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java @@ -153,6 +153,7 @@ public class LibraryProductImpl extends BaseServiceImpl libraryProductIds= libraryProductList.stream().map(LibraryProduct::getId).collect(Collectors.toList()); QueryWrapper queryWrapperImage = new QueryWrapper<>(); queryWrapperImage.in("product_id", libraryProductIds); + queryWrapperImage.eq("is_main",0); List libraryProductImageList= libraryProductImageService.list(queryWrapperImage); Map> listMap=new HashMap<>(); From 45469be52dada7c16fdd3881b9b9f6b745a86d8e Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 26 Nov 2025 11:19:58 +0800 Subject: [PATCH 40/81] =?UTF-8?q?1=E3=80=81=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E5=95=86=E5=93=81=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9=EF=BC=8C?= =?UTF-8?q?2=E3=80=81=E5=AE=A2=E6=88=B7=E7=AB=AF=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B79.7=E5=92=8C=E5=95=86=E4=BA=9110?= =?UTF-8?q?=E5=88=86=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/Schedule/DynamicTaskScheduler.java | 55 +++-- .../com/small/client/Utils/FileUtils.java | 19 +- .../java/com/small/client/dao/BaseDao.java | 16 +- .../java/com/small/client/dao/SxDataDao.java | 188 +++++++++++++++++- .../com/small/client/dto/DataBaseInfo.java | 13 ++ .../java/com/small/client/dto/RmSaleflow.java | 22 +- .../com/small/client/dto/StoreDbConfig.java | 9 + .../com/small/client/dto/SxGoosModel.java | 3 + .../java/com/small/client/dto/TRmPayflow.java | 9 +- .../service/SxDataAbst/SxDataAbstService.java | 1 + .../small/client/service/SxDataService.java | 6 + .../client/service/imp/SxDataServiceImp.java | 45 +++-- 12 files changed, 321 insertions(+), 65 deletions(-) diff --git a/client/src/main/java/com/small/client/Schedule/DynamicTaskScheduler.java b/client/src/main/java/com/small/client/Schedule/DynamicTaskScheduler.java index 40ef8277..9cec2163 100644 --- a/client/src/main/java/com/small/client/Schedule/DynamicTaskScheduler.java +++ b/client/src/main/java/com/small/client/Schedule/DynamicTaskScheduler.java @@ -34,16 +34,21 @@ public class DynamicTaskScheduler { this.sxDataService = sxDataService; } - @PostConstruct + @PostConstruct public void initTasks() { - //初始化 start - CommentModel commentModel =sxDataService.getCommentModel(); - DataBaseInfo enabledTask = sxDataService.getDataBaseInfo(commentModel); - executeTask(enabledTask.getDataBaseName(),commentModel); - //初始化 end - refreshTasks(); - // 每5分钟检查一次数据库更新 - taskScheduler.scheduleAtFixedRate(this::refreshTasks, Duration.ofHours(1)); + try { + //初始化 start + CommentModel commentModel =sxDataService.getCommentModel(); + DataBaseInfo enabledTask = sxDataService.getDataBaseInfo(commentModel); + executeTask(enabledTask.getDataBaseName(),commentModel); + //初始化 end + refreshTasks(); + // 每5分钟检查一次数据库更新 + taskScheduler.scheduleAtFixedRate(this::refreshTasks, Duration.ofHours(1)); + }catch (Exception e){ + log.info("系统异常:{}",e.getMessage()); + } + } public void refreshTasks() { @@ -104,12 +109,13 @@ public class DynamicTaskScheduler { refreshTime=DateUtil.formatDateTime(dataBaseInfo.getRefreshTime()); commentModel.setSyncTime(refreshTime); } - sxDataService.syncStoreData(dataBaseInfo,commentModel); + sxDataService.syncStoreData(dataBaseInfo,commentModel);//同步网上售卖流水 + if(StringUtils.isNotEmpty(refreshTime)){//有刷新时间,证明不是全量,需要判断是否有新商品,有新商品才同步品牌和分类 - if(sxDataService.isNewShop(dataBaseInfo,refreshTime)){ - sxDataService.SyncBranchList(dataBaseInfo,commentModel); - sxDataService.SyncCategory(dataBaseInfo,commentModel); - } + if(sxDataService.isNewShop(dataBaseInfo,refreshTime)){ + sxDataService.SyncBranchList(dataBaseInfo,commentModel); + sxDataService.SyncCategory(dataBaseInfo,commentModel); + } }else { log.info("首次同步,无刷新时间"); sxDataService.SyncBranchList(dataBaseInfo,commentModel); @@ -129,15 +135,22 @@ public class DynamicTaskScheduler { if(ObjectUtil.isNotEmpty(dataBaseInfo.getRefreshTime())){ commentModel.setSyncTime(refreshTime); } - sxDataService.SyncVipList(dataBaseInfo,commentModel); - boolean isNewActives=sxDataService.syncAtive(dataBaseInfo,commentModel); - if(isNewActives){ - log.info("---有新增的活动,同步活动商品开始--"); - sxDataService.syncAtiveShops(dataBaseInfo,commentModel); - }else { - log.info("---无新增的活动,无需同步活动商品--"); + if("1".equals(dataBaseInfo.getIsSyncMember())){//同步会员 + sxDataService.SyncVipList(dataBaseInfo,commentModel); } + //同步活动数据,判断是否同步活动数据,有新活动,且有活动数据才同步活动 + if("1".equals(dataBaseInfo.getIsSyncActive())){ + boolean isNewActives=sxDataService.syncAtive(dataBaseInfo,commentModel); + if(isNewActives){ + log.info("---有新增的活动,同步活动商品开始--"); + sxDataService.syncAtiveShops(dataBaseInfo,commentModel); + }else { + log.info("---无新增的活动,无需同步活动商品--"); + } + } + + sxDataService.refreshTime(commentModel); isRuning=false; } diff --git a/client/src/main/java/com/small/client/Utils/FileUtils.java b/client/src/main/java/com/small/client/Utils/FileUtils.java index b865a8da..839f05ae 100644 --- a/client/src/main/java/com/small/client/Utils/FileUtils.java +++ b/client/src/main/java/com/small/client/Utils/FileUtils.java @@ -36,7 +36,7 @@ public class FileUtils { public static final String okEnd = "ok";//后缀 public static final String txtEnd = "txt";//后缀 - public static String fileFormat = "%s_%s.%s";//good_1 + public static String fileFormat = "%s_%s_%s.%s";//good_1 public static String getSyncTypeFlag(String syncType){ Calendar calendar=Calendar.getInstance(); @@ -96,12 +96,21 @@ public class FileUtils { * @param filePath */ public void writeFile(String filePath,String fileName,String content){ + FileWriter writer =null; try { - FileWriter writer = new FileWriter(filePath+pathSeparator+fileName); + writer = new FileWriter(filePath+pathSeparator+fileName,false); writer.write(content); + writer.flush(); writer.close(); log.info("文件写入成功!"); } catch (IOException e) { + if(writer!=null){ + try { + writer.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } log.info("文件写入失败:{}", e.getMessage()); } } @@ -112,7 +121,7 @@ public class FileUtils { * @param page * @return */ - public String getFileName(String syncType ,Integer page,String endFix){ + public String getFileName(String syncType ,Integer page,String endFix,String fileEndFix){ String result=""; switch (syncType){ case "1": @@ -130,7 +139,7 @@ public class FileUtils { default: break; } - return String.format(fileFormat, result,page,endFix); + return String.format(fileFormat, result,page,fileEndFix,endFix); } /** @@ -170,7 +179,7 @@ public class FileUtils { FileUtils fileUtils= new FileUtils(); File file=fileUtils.createFile("1",1); System.out.printf("--"+file.getAbsoluteFile()); - fileUtils.writeFile(file.getAbsolutePath(),fileUtils.getFileName("1",2,txtEnd),"456"); + fileUtils.writeFile(file.getAbsolutePath(),fileUtils.getFileName("1",2,txtEnd,"operate"),"456"); } } diff --git a/client/src/main/java/com/small/client/dao/BaseDao.java b/client/src/main/java/com/small/client/dao/BaseDao.java index f73f2dcd..cb8492db 100644 --- a/client/src/main/java/com/small/client/dao/BaseDao.java +++ b/client/src/main/java/com/small/client/dao/BaseDao.java @@ -284,7 +284,7 @@ public class BaseDao { // " ls.oper_date " + "FROM ( " + " SELECT " + - " ROW_NUMBER() OVER(ORDER BY item_clsno) AS rowId, " + + " ROW_NUMBER() OVER(ORDER BY item_clsno,item_no) AS rowId, " + " * " + " FROM t_bd_item_info shop %s" + ") b " + @@ -355,21 +355,21 @@ public class BaseDao { " tib.oper_date," + " ROW_NUMBER() OVER(PARTITION BY tib.item_no ORDER BY tib.oper_date DESC) AS rn " + " FROM t_im_branch_stock tib " + - ") " + - "SELECT " + - "ROW_NUMBER() OVER (ORDER BY b.rowId) AS rowId, "+//-- 这里重新生成从1开始连续的行号 + "), " + + "PagedData As( SELECT " + + "ROW_NUMBER() OVER (ORDER BY b.rowId) AS rowIdA, "+//-- 这里重新生成从1开始连续的行号 " b.*, " + " ls.stock_qty, " + " ls.oper_date " + "FROM ( " + " SELECT " + - " ROW_NUMBER() OVER(ORDER BY item_clsno) AS rowId ," + + " ROW_NUMBER() OVER(ORDER BY item_clsno,item_no) AS rowId ," + " * " + " FROM t_bd_item_info shop %s" + ") b " + - "LEFT JOIN LatestStock ls ON b.item_no = ls.item_no AND ls.rn = 1 " + - " where b.rowId BETWEEN %s AND %s %s"; - sql=String.format(sql,where,start,end,stockOperateWhere); + "LEFT JOIN LatestStock ls ON b.item_no = ls.item_no AND ls.rn = 1 %s) " + + "SELECT * FROM PagedData where rowIdA BETWEEN %s AND %s "; + sql=String.format(sql,where,stockOperateWhere,start,end); log.info(sql); ResultDto resultDto=new ResultDto(); ResultSet rs=null; diff --git a/client/src/main/java/com/small/client/dao/SxDataDao.java b/client/src/main/java/com/small/client/dao/SxDataDao.java index 6d004280..2e7fb11e 100644 --- a/client/src/main/java/com/small/client/dao/SxDataDao.java +++ b/client/src/main/java/com/small/client/dao/SxDataDao.java @@ -206,7 +206,7 @@ public class SxDataDao extends BaseDao{ public List findBditemInfoListPage(DataBaseInfo dataBaseInfo,int pageNo,int pageSize){ String stockOperateWhere=""; if(StringUtils.isNotEmpty(dataBaseInfo.getStockOperateWhere())){ - stockOperateWhere=" and "+dataBaseInfo.getStockOperateWhere(); + stockOperateWhere=" where "+dataBaseInfo.getStockOperateWhere(); } ResultDto resultDto=baseFindGoodsListJoinPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName() ,pageNo,pageSize,dataBaseInfo.getWhere()==null?DEFALTWHERE:dataBaseInfo.getWhere(),stockOperateWhere); @@ -230,6 +230,7 @@ public class SxDataDao extends BaseDao{ }else { sxSyncGoods.setGross_margin(new BigDecimal("0"));//毛利率 } + sxSyncGoods.setId(rs.getLong("rowIdA")); sxSyncGoods.setItem_no(rs.getString("item_no"));//货号 sxSyncGoods.setItem_subname(rs.getString("item_name"));//商品名称 sxSyncGoods.setItem_subno(rs.getString("item_subno"));//商品条码 @@ -509,6 +510,7 @@ public class SxDataDao extends BaseDao{ ") " + " UPDATE TopStock " + " SET stock_qty = stock_qty+(?),oper_date=?;"; + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); try (PreparedStatement ps = conn.prepareStatement(sql)) { int batchSize = 100; // 每批处理1000条 @@ -552,7 +554,13 @@ public class SxDataDao extends BaseDao{ int[] remainingCounts = ps.executeBatch(); //todo 新增流水 - updateStoreSaleFlow(conn,rmSaleflowList,tRmPayflowList); + if(dataBaseInfo.getClientVersion().equals(DataBaseInfo.SHANG_YUN)){ + updateStoreSaleFlow(conn,rmSaleflowList,tRmPayflowList); + } + if (dataBaseInfo.getClientVersion().equals(DataBaseInfo.SHANG_RUI)){ + updateStoreSaleFlowShangRui(conn,rmSaleflowList,tRmPayflowList); + } + List consumIds=productQuantityConsumptionDtoList .stream() @@ -605,6 +613,11 @@ public class SxDataDao extends BaseDao{ rmSaleflow.setSaleMoney(productQuantityConsumptionDto.getSaleAmount()); // rmSaleflow.setSourcePrice(unitPrice); rmSaleflow.setFlownoRand(productQuantityConsumptionDto.getOrderId());//随机子单号 设置网上订单号 + if(null!=productQuantityConsumptionDto.getSaleTime()){ + rmSaleflow.setOperDate(new Timestamp(productQuantityConsumptionDto.getSaleTime())); + }else { + rmSaleflow.setOperDate(new Timestamp(System.currentTimeMillis())); + } return rmSaleflow; } @@ -627,7 +640,7 @@ public class SxDataDao extends BaseDao{ //判断取值 start rmSaleflow.setSellWay("B"); - rmSaleflow.setRetQnty(rmSaleflow.getSaleQnty()); + rmSaleflow.setRetQnty(BigDecimal.ZERO); if(rmSaleflow.getSaleQnty().compareTo(BigDecimal.ZERO)<0){ rmSaleflow.setSellWay("A"); BigDecimal saleQnty=rmSaleflow.getSaleQnty();//销售数量 @@ -646,7 +659,6 @@ public class SxDataDao extends BaseDao{ if(itemInfo!=null){ rmSaleflow.setInPrice(itemInfo.getPrice()); rmSaleflow.setSourcePrice(itemInfo.getSalePrice()); - rmSaleflow.setOperDate(new Timestamp(System.currentTimeMillis())); } rmSaleflow.setBranchNo(branchNo); @@ -665,6 +677,8 @@ public class SxDataDao extends BaseDao{ rmSaleflow.setPrefAmt(BigDecimal.ZERO); rmSaleflow.setComFlag("0"); rmSaleflow.setRemoteFlag("0"); + rmSaleflow.setPaysum_flag("0"); + rmSaleflow.setKz_flag("1"); //统一默认值 end return rmSaleflow; } @@ -691,7 +705,7 @@ public class SxDataDao extends BaseDao{ rmPayflow.setCoinNo("RMB");// rmPayflow.setCoinRate(new BigDecimal("1"));//利率 rmPayflow.setPayAmount(rmSaleflow.getSaleMoney()); - rmPayflow.setOperDate(new Timestamp(System.currentTimeMillis())); + rmPayflow.setOperDate(rmSaleflow.getOperDate()); rmPayflow.setOperId(rmSaleflow.getOperId()); rmPayflow.setCounterNo(rmSaleflow.getCounterNo()); rmPayflow.setSaleMan(rmSaleflow.getSaleMan()); @@ -784,7 +798,7 @@ public class SxDataDao extends BaseDao{ } /** - * 批量新增销售流水 + * 批量新增销售流水 商云10 * @param conn * @param rmSaleflowList */ @@ -802,8 +816,8 @@ public class SxDataDao extends BaseDao{ "sale_qnty, sale_money, sell_way, oper_id, sale_man, counter_no, " + "oper_date, remote_flag, shift_no, com_flag, spec_flag, pref_amt, " + "in_price, n_stan, chr_stan, posid, uptime, flowno_rand, ret_qnty, " + - "flowno_type, spec_sheet_no, cic_sheet_no, share_cardid, item_no_Fresh" + - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "flowno_type, spec_sheet_no, cic_sheet_no" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; String sql2 = "INSERT INTO t_rm_payflow (" + "flow_id, flow_no, sale_amount, branch_no, pay_way, sell_way, " + "card_no, vip_no, coin_no, coin_rate, pay_amount, oper_date, " + @@ -857,8 +871,8 @@ public class SxDataDao extends BaseDao{ ps.setString(26, rmSaleflow.getFlownoType()); ps.setString(27, rmSaleflow.getSpecSheetNo()); ps.setString(28, "");//CicSheetNo - ps.setString(29, rmSaleflow.getShareCardid()); - ps.setString(30, rmSaleflow.getItemNoFresh()); +// ps.setString(29, rmSaleflow.getShareCardid()); +// ps.setString(30, rmSaleflow.getItemNoFresh()); ps.addBatch(); // 添加至批处理 //rmSaleflow end------------- @@ -937,6 +951,160 @@ public class SxDataDao extends BaseDao{ // } } + /** + * 批量新增销售流水 商瑞9.7 + * @param conn + * @param rmSaleflowList + */ + public void updateStoreSaleFlowShangRui(Connection conn,List rmSaleflowList,List payflowList){ + if(CollectionUtil.isEmpty(rmSaleflowList)){ + log.info("销售流水记录为空"); + return; + } +// Connection conn =getConnection(dataBaseInfo.getIp(),dataBaseInfo.getUserName(), +// dataBaseInfo.getPassword(), dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName()); + //try { + //conn.setAutoCommit(false); // 关闭自动提交,开启事务 + String sql = "INSERT INTO t_rm_saleflow (" + + "flow_id, flow_no, branch_no, item_no, source_price, sale_price, " + + "sale_qnty, sale_money, sell_way, oper_id, sale_man, counter_no, " + + "oper_date, remote_flag, shift_no, com_flag, spec_flag, pref_amt, " + + "in_price, n_stan, chr_stan, posid, uptime, " + + "paysum_flag, spec_sheet_no,kz_flag, update_date" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)"; + String sql2 = "INSERT INTO t_rm_payflow (" + + "flow_id, flow_no, sale_amount, branch_no, pay_way, sell_way, " + + "card_no, vip_no, coin_no, coin_rate, pay_amount, oper_date, " + + "oper_id, counter_no, sale_man, memo,remote_flag, " + + "exchange_flag, shift_no, com_flag, uptime, " + + "kz_no" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + try { + PreparedStatement ps = conn.prepareStatement(sql);//销售流水 + PreparedStatement ps2 = conn.prepareStatement(sql2);//资金流水 + int batchSize = 10; // 每批处理10条 + int count = 0; + for (int i=0;i'"+dataBaseInfo.getPriceOperatime()+"' " + " )"; + fileEndFix="price"; } dataBaseInfo.setWhere(where); // 记录总数 @@ -401,11 +405,11 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService } catch (JsonProcessingException e) { throw new RuntimeException(e); } - String code= writeToFileAndUploud(i,jsonString,commentModel,DicEnum.MUAL_1.getCode()); + String code= writeToFileAndUploud(i,jsonString,commentModel,DicEnum.MUAL_1.getCode(),fileEndFix); if (!HttpUtils.SUCCESSCODE.equals(code)) { continue; } - folders.add(String.valueOf(i)); + folders.add(i+"_"+fileEndFix); syncCount+=sxSyncGoods.size(); } //通知服务器上传cos @@ -435,15 +439,15 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService * @param commentModel * @return */ - private String writeToFileAndUploud(Integer page,String content,CommentModel commentModel,String syncType){ + private String writeToFileAndUploud(Integer page,String content,CommentModel commentModel,String syncType,String fileEndFix){ FileUtils fileUtils= new FileUtils(); File file=fileUtils.createFile(syncType,page); - String fileName=fileUtils.getFileName(syncType,page,FileUtils.txtEnd); + String fileName=fileUtils.getFileName(syncType,page,FileUtils.txtEnd,fileEndFix); String filePath=file.getAbsolutePath(); fileUtils.writeFile(filePath,fileName,content); String sign=CommonUtil.generateOpenSign(content,commentModel.getAppKey(),commentModel.getAppId()); commentModel.setSign(sign); - return webClientService.uploudSxData(filePath+FileUtils.pathSeparator+fileName,commentModel,page.toString(),syncType); + return webClientService.uploudSxData(filePath+FileUtils.pathSeparator+fileName,commentModel,page+"_"+fileEndFix,syncType); } /** @@ -766,6 +770,9 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService dataBaseInfo.setIsTowSync(storeDbConfig.getIsTowSync()); dataBaseInfo.setShopGapTime(storeDbConfig.getShopGapTime()); dataBaseInfo.setSaleAccount(storeDbConfig.getSaleAccount()); + dataBaseInfo.setIsSyncActive(storeDbConfig.getIsSyncActive()); + dataBaseInfo.setIsSyncMember(storeDbConfig.getIsSyncMember()); + dataBaseInfo.setClientVersion(storeDbConfig.getClientVersion()); return dataBaseInfo; } return new DataBaseInfo(); @@ -786,7 +793,8 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService +"?appKey="+commentModel.getAppKey() +"&sign="+commentModel.getAppId(),JSONObject.class); // String jsonStr="[{\"consumeId\":\"1986611923814223873\",\"orderId\":\"DD_20251107_1\",\"productNumber\":\"31011\",\"unitPrice\":10.90,\"quantity\":1.500,\"saleAmount\":16.35,\"status\":0,\"storeId\":78,\"createTime\":\"2025-11-07 01:49:26\",\"updateTime\":\"2025-11-07 01:49:26\"},{\"consumeId\":\"1986611923814223872\",\"orderId\":\"DD_20251107_2\",\"productNumber\":\"6909409023853\",\"unitPrice\":1.00,\"quantity\":1.000,\"saleAmount\":1.00,\"status\":0,\"storeId\":78,\"createTime\":\"2025-11-07 01:49:26\",\"updateTime\":\"2025-11-07 01:49:26\"},{\"consumeId\":\"1986611923814223874\",\"orderId\":\"DD_20251107_1\",\"productNumber\":\"6909409023853\",\"unitPrice\":1.00,\"quantity\":2.000,\"saleAmount\":2.00,\"status\":0,\"storeId\":78,\"createTime\":\"2025-11-07 01:49:26\",\"updateTime\":\"2025-11-07 01:49:26\"}]"; - + //String jsonObjectStr="{\"error_code\":0,\"error_msg\":\"success\",\"result\":[{\"consumeId\":\"1993254597656690689\",\"orderId\":\"DD_20251125_2\",\"productNumber\":\"10035\",\"unitPrice\":16.00,\"quantity\":-0.500,\"saleAmount\":8.00,\"status\":0,\"storeId\":78,\"createTime\":\"2025-11-25 09:45:03\",\"updateTime\":\"2025-11-25 09:45:03\",\"saleTime\":1764063651000},{\"consumeId\":\"1993254597656690688\",\"orderId\":\"DD_20251125_2\",\"productNumber\":\"6922896008127\",\"unitPrice\":8.80,\"quantity\":-1.000,\"saleAmount\":8.80,\"status\":0,\"storeId\":78,\"createTime\":\"2025-11-25 09:45:03\",\"updateTime\":\"2025-11-25 09:45:03\",\"saleTime\":1764063651000}]}"; + // JSONObject jsonObject=JSONUtil.parseObj(jsonObjectStr); if(null!=jsonObject.get("result")){ // Map map=(Map)jsonObject.get("result"); String jsonStr= jsonObject.getStr("result"); @@ -807,7 +815,6 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService productQuantityConsumptionDtoList.forEach(productQuantityConsumptionDto -> { productQuantityConsumptionDtoMap.put(productQuantityConsumptionDto.getOrderId()+"-"+productQuantityConsumptionDto.getProductNumber(),productQuantityConsumptionDto); }); - sxDataDao.updateStoreData(dataBaseInfo,map,productQuantityConsumptionDtoMap,productQuantityConsumptionDtoList,commentModel); }else { log.info("无线上流水同步"); @@ -867,9 +874,9 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService dataBaseInfo.setWhere(where); total = sxDataDao.getTotalSpecShop(dataBaseInfo); if(total==0){ - HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_REFRESH - +"?appKey="+commentModel.getAppKey() - +"&sign="+commentModel.getAppId(), new JSONArray()); +// HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_REFRESH +// +"?appKey="+commentModel.getAppKey() +// +"&sign="+commentModel.getAppId(), new JSONArray()); log.info("暂无活动商品同步"); return; } @@ -897,9 +904,9 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService syncCount+=activeDtos.size(); } log.info("成功同步活动商品数据:"+syncCount); - HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_REFRESH - +"?appKey="+commentModel.getAppKey() - +"&sign="+commentModel.getAppId(), new JSONArray()); +// HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_REFRESH +// +"?appKey="+commentModel.getAppKey() +// +"&sign="+commentModel.getAppId(), new JSONArray()); } @@ -913,4 +920,12 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService return map; } + + @Override + public void refreshTime(CommentModel commentModel) { + HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_REFRESH + +"?appKey="+commentModel.getAppKey() + +"&sign="+commentModel.getAppId(), new JSONArray()); + } + } From fb10c6e17382435766670c5a6b295ee454740c80 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 10:13:08 +0800 Subject: [PATCH 41/81] =?UTF-8?q?=E5=9B=BE=E5=BA=93=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/shop/library/service/impl/LibraryProductImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java index ff746a06..2f0b5ec6 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java @@ -158,7 +158,7 @@ public class LibraryProductImpl extends BaseServiceImpl> listMap=new HashMap<>(); libraryProductImageList.forEach(libraryProductImage -> { - libraryProductImage.setImageUrl(staticDomain+libraryProductImage.getImageUrl()); + libraryProductImage.setImageUrl(com.suisung.mall.common.utils.CommonUtil.addDomainPrefix(staticDomain,libraryProductImage.getImageUrl())); List productImageList=listMap.get(libraryProductImage.getProductId()); if(null==productImageList){ productImageList=new ArrayList<>(); @@ -168,7 +168,7 @@ public class LibraryProductImpl extends BaseServiceImpl{ - libraryProduct.setThumb(staticDomain+libraryProduct.getThumb()); + libraryProduct.setThumb(com.suisung.mall.common.utils.CommonUtil.addDomainPrefix(staticDomain,libraryProduct.getThumb())); if(null==listMap.get(libraryProduct.getId())){ libraryProduct.setProduct_image_list(Collections.emptyList()); }else { From 4e2a75520ccfcb0afc51b1bb992d0b717e34cdab Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 10:13:28 +0800 Subject: [PATCH 42/81] =?UTF-8?q?=E5=9B=BE=E5=BA=93=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/suisung/mall/common/utils/CommonUtil.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java b/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java index 7ccb6d9c..635cd960 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/CommonUtil.java @@ -509,7 +509,19 @@ public class CommonUtil { } return tpl_label; } - + /** + * 为URL添加域名前缀(如果URL不是以http/https开头) + * + * @param imageDomain 图片域名 + * @param url 图片URL + * @return 添加域名前缀后的URL + */ + public static String addDomainPrefix(String imageDomain, String url) { + if (url == null || url.startsWith("http://") || url.startsWith("https://")) { + return url; + } + return imageDomain + (url.startsWith("/") ? url : "/" + url); + } public static void main(String[] args) { System.out.println("测试1分钱分配:"); From 504f03e5f61ad9b1972e0137cb02ffaaf0315d8f Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 14:57:50 +0800 Subject: [PATCH 43/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/sync/service/impl/SyncThirdDataServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java index ddff290b..70752993 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncThirdDataServiceImpl.java @@ -631,8 +631,9 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements String fileIndex=folders.get(0); String fileEndFix; - if (fileIndex.length()>1){ - fileEndFix=fileIndex.split("_")[1]; + String [] fileIndexArray=fileIndex.split("_"); + if (fileIndexArray.length>1){ + fileEndFix=fileIndexArray[1]; } else { fileEndFix = ""; } From c0f11aa2243bbda18fcfb18c8d19bac5bce2ceb2 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 15:00:33 +0800 Subject: [PATCH 44/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E4=B8=8E=E6=9B=B4=E6=96=B0=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/small/client/dao/BaseDao.java | 56 ++++++++++++++++++ .../java/com/small/client/dao/SxDataDao.java | 27 +++++++-- .../dto/ProductQuantityConsumptionDto.java | 3 + .../service/SxDataAbst/SxDataAbstService.java | 58 ++++++++++--------- .../client/service/imp/SxDataServiceImp.java | 4 +- 5 files changed, 114 insertions(+), 34 deletions(-) diff --git a/client/src/main/java/com/small/client/dao/BaseDao.java b/client/src/main/java/com/small/client/dao/BaseDao.java index cb8492db..589eadcf 100644 --- a/client/src/main/java/com/small/client/dao/BaseDao.java +++ b/client/src/main/java/com/small/client/dao/BaseDao.java @@ -385,6 +385,62 @@ public class BaseDao { return resultDto; } + /** + * 全量查询 + * @param ip + * @param username + * @param password + * @param portNumber + * @param dataBaseName + * @param pageNo + * @param pageSize + * @param where + * @param stockOperateWhere + * @return + */ + public ResultDto baseFindAllGoodsListJoinPage(String ip, String username, String password,Integer portNumber, String dataBaseName, int pageNo, int pageSize, + String where,String stockOperateWhere){ + Connection connection=getConnection(ip,username,password,portNumber,dataBaseName); + int start=(pageNo-1)*pageSize+1; + int end=pageNo*pageSize; + String sql="SELECT * " + + "FROM (" + + " SELECT " + + " ROW_NUMBER() OVER(ORDER BY shop.item_clsno, shop.item_no) AS rowIdA," + + " shop.*," + + " (\n" + + " SELECT TOP 1 stock_qty " + + " FROM t_im_branch_stock " + + " WHERE item_no = shop.item_no " + + " ORDER BY oper_date DESC " + + " ) as stock_qty,\n" + + " (\n" + + " SELECT TOP 1 oper_date " + + " FROM t_im_branch_stock " + + " WHERE item_no = shop.item_no " + + " ORDER BY oper_date DESC " + + " ) as oper_date " + + " FROM t_bd_item_info shop " + + " %s " + + ") t " + + "WHERE rowIdA BETWEEN %s AND %s " + + "ORDER BY rowIdA;"; + sql=String.format(sql,where,start,end); + log.info(sql); + ResultDto resultDto=new ResultDto(); + ResultSet rs=null; + try { + PreparedStatement ps= connection.prepareStatement(sql); + rs = ps.executeQuery(); + } catch (SQLException e) { + log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.baseFindListJoinPage",e.getMessage()); + throw new RuntimeException(e); + } + resultDto.setResultSet(rs); + resultDto.setConnection(connection); + return resultDto; + } + /** * * @param ip diff --git a/client/src/main/java/com/small/client/dao/SxDataDao.java b/client/src/main/java/com/small/client/dao/SxDataDao.java index 2e7fb11e..67727c77 100644 --- a/client/src/main/java/com/small/client/dao/SxDataDao.java +++ b/client/src/main/java/com/small/client/dao/SxDataDao.java @@ -127,9 +127,15 @@ public class SxDataDao extends BaseDao{ try { while (rs.next()) { sxSyncCategory=new SxSyncCategory(); - sxSyncCategory.setItem_clsname(rs.getString("item_clsname"));//分类名称 - sxSyncCategory.setCls_parent(rs.getString("cls_parent"));//父级编码 - sxSyncCategory.setItem_clsno(rs.getString("item_clsno"));//分类编码 + if(StringUtils.isNotEmpty(rs.getString("item_clsname"))){ + sxSyncCategory.setItem_clsname(rs.getString("item_clsname").trim());//分类名称 + } + if(StringUtils.isNotEmpty(rs.getString("cls_parent"))){ + sxSyncCategory.setCls_parent(rs.getString("cls_parent").trim());//父级编码 + } + if(StringUtils.isNotEmpty(rs.getString("item_clsno"))){ + sxSyncCategory.setItem_clsno(rs.getString("item_clsno").trim());//分类编码 + } // System.out.printf(rs.getString("item_clsno"));//分类编码 // log.info(rs.getString("item_clsname")+"\t");//分类名称 //log.info(rs.getString("cls_parent")+"\t");//父级编码 @@ -203,13 +209,22 @@ public class SxDataDao extends BaseDao{ * @param pageNo * @param pageSize */ - public List findBditemInfoListPage(DataBaseInfo dataBaseInfo,int pageNo,int pageSize){ + public List findBditemInfoListPage(DataBaseInfo dataBaseInfo,int pageNo,int pageSize,boolean isAll){ String stockOperateWhere=""; if(StringUtils.isNotEmpty(dataBaseInfo.getStockOperateWhere())){ stockOperateWhere=" where "+dataBaseInfo.getStockOperateWhere(); } - ResultDto resultDto=baseFindGoodsListJoinPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName() - ,pageNo,pageSize,dataBaseInfo.getWhere()==null?DEFALTWHERE:dataBaseInfo.getWhere(),stockOperateWhere); + + ResultDto resultDto=null; + if(!isAll){ + resultDto=baseFindGoodsListJoinPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName() + ,pageNo,pageSize,dataBaseInfo.getWhere()==null?DEFALTWHERE:dataBaseInfo.getWhere(),stockOperateWhere); + }else { + resultDto=baseFindAllGoodsListJoinPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName() + ,pageNo,pageSize,dataBaseInfo.getWhere()==null?DEFALTWHERE:dataBaseInfo.getWhere(),stockOperateWhere); + } + + ResultSet rs= resultDto.getResultSet(); List sxSyncGoodses=new ArrayList<>(); SxSyncGoods sxSyncGoods=null; diff --git a/client/src/main/java/com/small/client/dto/ProductQuantityConsumptionDto.java b/client/src/main/java/com/small/client/dto/ProductQuantityConsumptionDto.java index 75564364..ff4b3db9 100644 --- a/client/src/main/java/com/small/client/dto/ProductQuantityConsumptionDto.java +++ b/client/src/main/java/com/small/client/dto/ProductQuantityConsumptionDto.java @@ -45,4 +45,7 @@ public class ProductQuantityConsumptionDto { @ApiModelProperty(value = "更新时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; + + @ApiModelProperty(value = "下单时间") + private Long saleTime; } diff --git a/client/src/main/java/com/small/client/service/SxDataAbst/SxDataAbstService.java b/client/src/main/java/com/small/client/service/SxDataAbst/SxDataAbstService.java index ba7a7feb..d0280220 100644 --- a/client/src/main/java/com/small/client/service/SxDataAbst/SxDataAbstService.java +++ b/client/src/main/java/com/small/client/service/SxDataAbst/SxDataAbstService.java @@ -60,7 +60,7 @@ public abstract class SxDataAbstService { * @param allSxSyncCategories 所有分类 * @return */ - public List ConVToSxCategoryModel(List sxSyncCategories,List allSxSyncCategories, Map clsBrandMap) { + public List ConVToSxCategoryModel(List sxSyncCategories,List allSxSyncCategories, Map clsBrandMap) { if(CollectionUtil.isEmpty(sxSyncCategories)){ return new ArrayList<>(); } @@ -69,37 +69,41 @@ public abstract class SxDataAbstService { SxCategoryModel sxCategoryModel=null; while (iterator.hasNext()){ SxSyncCategory sxSyncCategory= iterator.next(); - sxCategoryModel=new SxCategoryModel(); - sxCategoryModel.setCategory_image(SxDataDao.DEFAULT_IMG); - sxCategoryModel.setCategory_name(sxSyncCategory.getItem_clsname()); - sxCategoryModel.setBrandName(clsBrandMap.get(sxSyncCategory.getItem_clsname())); - //寻找父级 - if(StringUtils.isNotEmpty(sxSyncCategory.getCls_parent())){ - SxSyncCategory firstNode=getParentNode(allSxSyncCategories,sxSyncCategory.getCls_parent()); - if(null==firstNode){ - sxCategoryModel.setFirst_category_name(""); - sxCategoryModel.setProduct_type(sxCategoryModel.getCategory_name()); - sxCategoryModels.add(sxCategoryModel); - continue; - } - sxCategoryModel.setParent_name(firstNode.getItem_clsname());//todo 暂时无用 - //如何存在上级的上级,则上级为第二层,上上及为第一层 - if(StringUtils.isNotEmpty(firstNode.getCls_parent())) {//还存在上级 - SxSyncCategory secondNode=getParentNode(allSxSyncCategories,firstNode.getCls_parent()); - if(null!=secondNode && secondNode.getItem_clsno().equals(firstNode.getCls_parent())){ - sxCategoryModel.setFirst_category_name(secondNode.getItem_clsname()); - sxCategoryModel.setSecond_category_name(firstNode.getItem_clsname()); + try { + sxCategoryModel=new SxCategoryModel(); + sxCategoryModel.setCategory_image(SxDataDao.DEFAULT_IMG); + sxCategoryModel.setCategory_name(sxSyncCategory.getItem_clsname()); + sxCategoryModel.setBrandName(clsBrandMap.get(sxSyncCategory.getItem_clsname())); + //寻找父级 + if(StringUtils.isNotEmpty(sxSyncCategory.getCls_parent())){ + SxSyncCategory firstNode=getParentNode(allSxSyncCategories,sxSyncCategory.getCls_parent()); + if(null==firstNode){ + sxCategoryModel.setFirst_category_name(""); + sxCategoryModel.setProduct_type(sxCategoryModel.getCategory_name()); + sxCategoryModels.add(sxCategoryModel); + continue; + } + sxCategoryModel.setParent_name(firstNode.getItem_clsname());//todo 暂时无用 + //如何存在上级的上级,则上级为第二层,上上及为第一层 + if(StringUtils.isNotEmpty(firstNode.getCls_parent())) {//还存在上级 + SxSyncCategory secondNode=getParentNode(allSxSyncCategories,firstNode.getCls_parent()); + if(null!=secondNode && secondNode.getItem_clsno().equals(firstNode.getCls_parent())){ + sxCategoryModel.setFirst_category_name(secondNode.getItem_clsname()); + sxCategoryModel.setSecond_category_name(firstNode.getItem_clsname()); + }else { + sxCategoryModel.setFirst_category_name(firstNode.getItem_clsname()); + } }else { sxCategoryModel.setFirst_category_name(firstNode.getItem_clsname()); } }else { - sxCategoryModel.setFirst_category_name(firstNode.getItem_clsname()); + sxCategoryModel.setFirst_category_name(""); } - }else { - sxCategoryModel.setFirst_category_name(""); + sxCategoryModel.setProduct_type(sxCategoryModel.getCategory_name()); + sxCategoryModels.add(sxCategoryModel); + }catch (Exception e){ + log.info("sxSyncCategory:{}",sxSyncCategory); } - sxCategoryModel.setProduct_type(sxCategoryModel.getCategory_name()); - sxCategoryModels.add(sxCategoryModel); } sxCategoryModels=filterCategories(sxCategoryModels); return sxCategoryModels; @@ -132,7 +136,7 @@ public abstract class SxDataAbstService { List list= sxSyncCategories.stream().filter(cc-> cc.getItem_clsno().trim().equals(parentId.trim())) .collect(Collectors.toList()); - return CollectionUtil.isNotEmpty(list)?list.get(0):new SxSyncCategory(); + return CollectionUtil.isNotEmpty(list)?list.get(0):null; } /** diff --git a/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java b/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java index 0b483805..361f22f9 100644 --- a/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java +++ b/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java @@ -334,6 +334,7 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService //String where="where 1=1"; String where="where shop.status='1'"; Integer total =0; + boolean isAll=false; String parentId=getAndCacheTree(dataBaseInfo,dataBaseInfo.getCategoryName());//加载缓存用的 String fileEndFix=""; if(DicEnum.SYNCTYPE_02.getCode().equals(dataBaseInfo.getSyncType())){ @@ -374,6 +375,7 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService total = sxDataDao.getTBditemInfoJoninTotal(dataBaseInfo); }else { where="where b.status='1'"; + isAll=true; dataBaseInfo.setWhere(where); total = sxDataDao.getTBditemInfoTotal(dataBaseInfo); where="where shop.status='1'"; @@ -396,7 +398,7 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService Date refreshDate= DateUtil.date(tenMinutesAgo); List folders=new ArrayList<>(); for (int i = 1; i <=pages; i++) { - List sxSyncGoods= sxDataDao.findBditemInfoListPage(dataBaseInfo,i,SxDataDao.PAGESIZE); + List sxSyncGoods= sxDataDao.findBditemInfoListPage(dataBaseInfo,i,SxDataDao.PAGESIZE,isAll); List sxGoosModelList= CvtToGoosModel(sxSyncGoods,specPriceDtoList); String jsonString=""; ObjectMapper objectMapper = new ObjectMapper(); From 857447ae8b6d312424b1141aadf1ec386b876bcb Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 15:44:04 +0800 Subject: [PATCH 45/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/order/service/impl/ShopOrderReturnServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index 9f9c423c..572f77ae 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1637,9 +1637,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); + String mapKey=item_src_id + "-" + returnItem.getReturn_id() + "-" + shopOrderItem.getOrder_item_unit_price(); if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ - mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id()); + mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 } stockDeltaMap.put(mapKey, returnNum); syncThirdDataService.incrProductStockToRedis(stockDeltaMap, returnItem.getReturn_item_subtotal()); From ed29dcd419d8798b9b1385088d2fd5eeaaec3f2a Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 16:25:31 +0800 Subject: [PATCH 46/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/order/service/impl/ShopOrderReturnServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index 572f77ae..b74327ad 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1637,7 +1637,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - String mapKey=item_src_id + "-" + returnItem.getReturn_id() + "-" + shopOrderItem.getOrder_item_unit_price(); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 } From 7e4c2a9ccf2bad6e740ed8c82ff89ff0b6bc6266 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 27 Nov 2025 17:50:46 +0800 Subject: [PATCH 47/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=EF=BC=8C=E6=97=A0=E5=87=BA?= =?UTF-8?q?=E5=BA=93=E4=B9=9F=E8=A6=81=E7=94=9F=E6=88=90=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ShopOrderReturnServiceImpl.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index b74327ad..c29626ae 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1643,10 +1643,40 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); + String item_src_id = productItem.getItem_src_id(); + String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); + if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ + mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 + } + stockDeltaMap.put(mapKey, returnNum); + syncThirdDataService.incrProductStockToRedis(stockDeltaMap, returnItem.getReturn_item_subtotal()); + logger.info("未出库退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{},mapKey:{}", item_src_id, shopOrderItem.getOrder_id(), returnNum,mapKey); + } } } } From e1bd542c1294377f9b8ed1fcf3eda0e0d947421c Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Fri, 28 Nov 2025 10:48:14 +0800 Subject: [PATCH 48/81] =?UTF-8?q?=E6=89=93=E5=8D=B0=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ductPrintVO.java => OrderItemPrintVO.java} | 12 +++--- .../mall/common/pojo/vo/OrderPrintVO.java | 25 ++++++++++++ .../common/pojo/vo/ShopStoreOrderPrintVO.java | 2 +- .../order/service/ShopOrderBaseService.java | 2 +- .../order/service/ShopOrderItemService.java | 4 +- .../impl/ShopOrderBaseServiceImpl.java | 20 +++++++--- .../impl/ShopOrderItemServiceImpl.java | 6 +-- .../impl/ShopOrderReturnServiceImpl.java | 30 +++++++------- .../impl/ShopStorePrinterServiceImpl.java | 4 +- .../mall/shop/store/utis/FeieUtil.java | 4 +- .../mapper/order/ShopOrderBaseMapper.xml | 32 +++++++++++++++ .../templates/refund_order_printer.txt | 39 ++++++++++++++++++- 12 files changed, 141 insertions(+), 39 deletions(-) rename mall-common/src/main/java/com/suisung/mall/common/pojo/vo/{ShopStoreOrderProductPrintVO.java => OrderItemPrintVO.java} (91%) create mode 100644 mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderProductPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java similarity index 91% rename from mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderProductPrintVO.java rename to mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java index 3bce33ac..883e2b20 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderProductPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java @@ -22,7 +22,7 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @ApiModel(value = "订单商品打印对象", description = "订单商品打印对象") -public class ShopStoreOrderProductPrintVO implements Serializable { +public class OrderItemPrintVO implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "商品名") private String item_name; @@ -47,11 +47,11 @@ public class ShopStoreOrderProductPrintVO implements Serializable { @ApiModelProperty(value = "金额额定字节长度") private Integer amount_blen; - public ShopStoreOrderProductPrintVO(String itemName, Integer orderItemQuantity, BigDecimal orderItemAmount, String productSn) { - new ShopStoreOrderProductPrintVO(itemName, orderItemQuantity, orderItemAmount, productSn, 18, 6, 8); + public OrderItemPrintVO(String itemName, Integer orderItemQuantity, BigDecimal orderItemAmount, String productSn) { + new OrderItemPrintVO(itemName, orderItemQuantity, orderItemAmount, productSn, 18, 6, 8); } - public ShopStoreOrderProductPrintVO(String itemName, Integer orderItemQuantity, BigDecimal orderItemAmount, String productSn, int titleBlen, int quantityBlen, int amountBlen) { + public OrderItemPrintVO(String itemName, Integer orderItemQuantity, BigDecimal orderItemAmount, String productSn, int titleBlen, int quantityBlen, int amountBlen) { this.item_name = itemName; this.order_item_quantity = orderItemQuantity; this.order_item_amount = orderItemAmount; @@ -90,8 +90,8 @@ public class ShopStoreOrderProductPrintVO implements Serializable { * * @return */ - public ShopStoreOrderProductPrintVO rebuild() { - return new ShopStoreOrderProductPrintVO(this.item_name, this.order_item_quantity, this.order_item_amount, this.product_sn, 18, 6, 8); + public OrderItemPrintVO rebuild() { + return new OrderItemPrintVO(this.item_name, this.order_item_quantity, this.order_item_amount, this.product_sn, 18, 6, 8); } /** diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java new file mode 100644 index 00000000..774f1c6a --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java @@ -0,0 +1,25 @@ +package com.suisung.mall.common.pojo.vo; + +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * 退货单打印对象 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(value = "(退款)订单主信息打印对象", description = "(退款)订单主信息打印对象") +public class OrderPrintVO implements Serializable { + private static final long serialVersionUID = 1L; + + +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java index 7f251c49..b0b32204 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java @@ -107,7 +107,7 @@ public class ShopStoreOrderPrintVO implements Serializable { // 订单商品详情信息 @ApiModelProperty(value = "订单商品详情信息") - private ShopStoreOrderProductPrintVO order_items; + private OrderItemPrintVO order_items; @ApiModelProperty(value = "状态:1-有效;2-无效;") private Integer status; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java index e60c32c2..41a68fe5 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java @@ -522,7 +522,7 @@ public interface ShopOrderBaseService extends IBaseService { * @param payState 支付状态,参考StateCode.ORDER_PAID_STATE_YES * @return */ - Map getOrderPrintInfo(Integer storeId, String orderId, Integer payState); + Map fetchOrderPrintInfo(Integer storeId, String orderId, Integer payState); /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderItemService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderItemService.java index 67018791..2ae3cf47 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderItemService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderItemService.java @@ -2,7 +2,7 @@ package com.suisung.mall.shop.order.service; import com.suisung.mall.common.modules.order.ShopOrderItem; import com.suisung.mall.common.modules.pay.dto.ItemActivityInfoDTO; -import com.suisung.mall.common.pojo.vo.ShopStoreOrderProductPrintVO; +import com.suisung.mall.common.pojo.vo.OrderItemPrintVO; import com.suisung.mall.core.web.service.IBaseService; import java.util.List; @@ -30,5 +30,5 @@ public interface ShopOrderItemService extends IBaseService { * @param orderId * @return */ - List selectOrderItemPrintInfo(String orderId); + List selectOrderItemPrintInfo(String orderId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 12d5cc15..8056b4ff 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -65,7 +65,7 @@ import com.suisung.mall.common.pojo.to.MsgTO; import com.suisung.mall.common.pojo.to.PayMoneyTO; import com.suisung.mall.common.pojo.to.PayPointTO; import com.suisung.mall.common.pojo.to.UserLevelTO; -import com.suisung.mall.common.pojo.vo.ShopStoreOrderProductPrintVO; +import com.suisung.mall.common.pojo.vo.OrderItemPrintVO; import com.suisung.mall.common.service.MessageService; import com.suisung.mall.common.service.impl.CommonService; import com.suisung.mall.common.utils.*; @@ -8765,8 +8765,16 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl shopStoreOrderProductPrintVOList = shopOrderItemService.selectOrderItemPrintInfo(orderId); - if (CollUtil.isEmpty(shopStoreOrderProductPrintVOList)) { + List orderItemPrintVOList = shopOrderItemService.selectOrderItemPrintInfo(orderId); + if (CollUtil.isEmpty(orderItemPrintVOList)) { return null; } // 重构实体类,处理标题,数量,价格适应长度 - List orderItems = new ArrayList<>(); - for (ShopStoreOrderProductPrintVO ent : shopStoreOrderProductPrintVOList) { + List orderItems = new ArrayList<>(); + for (OrderItemPrintVO ent : orderItemPrintVOList) { orderItems.add(ent.rebuild()); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderItemServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderItemServiceImpl.java index d2d4fd49..3ef2a698 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderItemServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderItemServiceImpl.java @@ -17,7 +17,7 @@ import com.suisung.mall.common.modules.order.ShopOrderDeliveryAddress; import com.suisung.mall.common.modules.order.ShopOrderInfo; import com.suisung.mall.common.modules.order.ShopOrderItem; import com.suisung.mall.common.modules.pay.dto.ItemActivityInfoDTO; -import com.suisung.mall.common.pojo.vo.ShopStoreOrderProductPrintVO; +import com.suisung.mall.common.pojo.vo.OrderItemPrintVO; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.activity.service.ShopActivityGroupbookingHistoryService; import com.suisung.mall.shop.order.mapper.ShopOrderItemMapper; @@ -226,7 +226,7 @@ public class ShopOrderItemServiceImpl extends BaseServiceImpl selectOrderItemPrintInfo(String orderId) { + public List selectOrderItemPrintInfo(String orderId) { // 输入验证 if (StrUtil.isBlank(orderId)) { return Collections.emptyList(); @@ -238,7 +238,7 @@ public class ShopOrderItemServiceImpl extends BaseServiceImpl { - ShopStoreOrderProductPrintVO vo = new ShopStoreOrderProductPrintVO(); + OrderItemPrintVO vo = new OrderItemPrintVO(); vo.setProduct_sn(Convert.toStr(map.get("product_sn"))); vo.setItem_name(Convert.toStr(map.get("item_name"))); vo.setOrder_item_amount(Convert.toBigDecimal(map.get("order_item_amount"))); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index c29626ae..e6425ea0 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1580,12 +1580,12 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl returnItemQueryWrapper = new QueryWrapper<>(); returnItemQueryWrapper.in("return_id", return_ids); List returnItems = orderReturnItemService.find(returnItemQueryWrapper); - QueryWrapper shopOrderReturnQueryWrapper= new QueryWrapper<>(); + QueryWrapper shopOrderReturnQueryWrapper = new QueryWrapper<>(); shopOrderReturnQueryWrapper.in("return_id", return_ids); - List shopOrderReturnList= shopOrderReturnService.find(shopOrderReturnQueryWrapper); - Map shopOrderReturnMap=new HashMap<>(); - if(!shopOrderReturnList.isEmpty()){ - shopOrderReturnMap=shopOrderReturnList.stream().collect(Collectors.toMap(ShopOrderReturn::getReturn_id, s->s.getUpdated_at().getTime())); + List shopOrderReturnList = shopOrderReturnService.find(shopOrderReturnQueryWrapper); + Map shopOrderReturnMap = new HashMap<>(); + if (!shopOrderReturnList.isEmpty()) { + shopOrderReturnMap = shopOrderReturnList.stream().collect(Collectors.toMap(ShopOrderReturn::getReturn_id, s -> s.getUpdated_at().getTime())); } if (CollUtil.isNotEmpty(returnItems)) { for (ShopOrderReturnItem returnItem : returnItems) { @@ -1637,17 +1637,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); - if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ - mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 + String mapKey = item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); + if (null != shopOrderReturnMap.get(returnItem.getReturn_id())) { + mapKey = mapKey + "-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 } stockDeltaMap.put(mapKey, returnNum); syncThirdDataService.incrProductStockToRedis(stockDeltaMap, returnItem.getReturn_item_subtotal()); - logger.info("退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{},mapKey:{}", item_src_id, shopOrderItem.getOrder_id(), returnNum,mapKey); + logger.info("退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{},mapKey:{}", item_src_id, shopOrderItem.getOrder_id(), returnNum, mapKey); } else { logger.warn("退货数量为空,无法增加库存,订单项ID: {}", orderItemId); } - }else {//没有出库也要做思迅出库,在客户端计算支付流水,防止部分数据有出无进 + } else {//没有出库也要做思迅出库,在客户端计算支付流水,防止部分数据有出无进 Long orderItemId = returnItem.getOrder_item_id(); ShopOrderItem shopOrderItem = shopOrderItemService.get(orderItemId); if (shopOrderItem == null) { @@ -1669,13 +1669,13 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl stockDeltaMap = new HashMap<>(); String item_src_id = productItem.getItem_src_id(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); - if(null!=shopOrderReturnMap.get(returnItem.getReturn_id())){ - mapKey=mapKey+"-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 + String mapKey = item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price(); + if (null != shopOrderReturnMap.get(returnItem.getReturn_id())) { + mapKey = mapKey + "-" + shopOrderReturnMap.get(returnItem.getReturn_id());//时间 } stockDeltaMap.put(mapKey, returnNum); syncThirdDataService.incrProductStockToRedis(stockDeltaMap, returnItem.getReturn_item_subtotal()); - logger.info("未出库退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{},mapKey:{}", item_src_id, shopOrderItem.getOrder_id(), returnNum,mapKey); + logger.info("未出库退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{},mapKey:{}", item_src_id, shopOrderItem.getOrder_id(), returnNum, mapKey); } } } @@ -2564,7 +2564,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl binding = shopOrderBaseService.getOrderPrintInfo(storeId, orderId, StateCode.ORDER_PAID_STATE_YES); + Map binding = shopOrderBaseService.fetchOrderPrintInfo(storeId, orderId, StateCode.ORDER_PAID_STATE_YES); if (binding == null) { logger.error("订单{}信息无法获取,无法打印小票。", orderId); return false; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/utis/FeieUtil.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/utis/FeieUtil.java index 3f0a5ae2..756ca615 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/utis/FeieUtil.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/utis/FeieUtil.java @@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.suisung.mall.common.pojo.res.FeiePrinterApiRes; -import com.suisung.mall.common.pojo.vo.ShopStoreOrderProductPrintVO; +import com.suisung.mall.common.pojo.vo.OrderItemPrintVO; import com.suisung.mall.common.utils.JsonUtil; import org.apache.commons.codec.digest.DigestUtils; import org.apache.http.HttpEntity; @@ -330,7 +330,7 @@ public class FeieUtil { * @param amountLen 金额字节数,最大8个字节 * @return */ - public String genProductStr(List productList, int titleLen, int numLen, int amountLen) { + public String genProductStr(List productList, int titleLen, int numLen, int amountLen) { String resultStr = ""; resultStr += "商品名称 数量 金额
"; resultStr += "--------------------------------
"; diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml index b18acf8f..b0aed8ec 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml @@ -565,6 +565,38 @@ + + diff --git a/mall-shop/src/main/resources/templates/refund_order_printer.txt b/mall-shop/src/main/resources/templates/refund_order_printer.txt index 7a9e5bba..a5d13886 100644 --- a/mall-shop/src/main/resources/templates/refund_order_printer.txt +++ b/mall-shop/src/main/resources/templates/refund_order_printer.txt @@ -37,7 +37,44 @@ --------------------------------
操作员:李小明
-格式化模版: +############################################ + +修改后的模版 + +小发同城
+--------------------------------
+#00019232
+退款原因:不用敲门,放在门口旁边的外卖箱,打个电话告知送达就行,谢谢!!!
+配送时间:2024-10-25 14:00-14:30
+--------------------------------
+订单编号:ES20231026111444527685
+退单编号:ES20231026111444527685
+订单来源:微信小程序
+支付方式:微信支付
+配送来源:顺丰同城
+付款时间:2024-10-25 14:00:23
+申请退款:2024-10-27 14:05:23
+确认退款:2024-10-27 14:8:23
+--------------------------------
+******* 退款商品 ******
+--------------------------------
+可口可乐CocaC x110 8100.45
+ola经典美味汽水1.2
+5L/瓶
+6970448170051
+排骨约350g(默 1 150.13
+认砍小块)
+6970448170053
+--------------------------------
+实付金额:¥428.9元
+申请退款:¥32.7
+退款方式:仅退款
+商家审批备注:商家发货少了
+--------------------------------
+会员名称:张三
+会员手机:13128778765
+--------------------------------
+操作员:李小明
原模版: From 30b24dda0402ff2c9bad1f180309395b726b2f62 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Fri, 28 Nov 2025 11:07:11 +0800 Subject: [PATCH 49/81] =?UTF-8?q?=E5=95=86=E5=93=81=E5=9B=BE=E5=BA=93?= =?UTF-8?q?=E9=99=84=E5=9B=BE=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/LibraryProductImpl.java | 21 +++++++++++++++---- .../mapper/library/LibraryProductMapper.xml | 6 +++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java index 2f0b5ec6..f0ef5b6a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/library/service/impl/LibraryProductImpl.java @@ -195,6 +195,7 @@ public class LibraryProductImpl extends BaseServiceImpl updateTableIds=new ArrayList<>(); List updateProductImageList=new ArrayList<>(); + List addProductImageList=new ArrayList<>(); products.forEach(product->{ if (null==product.getId()){ throw new ApiException("id is null"); @@ -207,10 +208,19 @@ public class LibraryProductImpl extends BaseServiceImpl - - - + + +
From 62239d4decec1cc944816f1c5b194a3061267b3c Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Fri, 28 Nov 2025 11:17:46 +0800 Subject: [PATCH 50/81] =?UTF-8?q?=E6=80=9D=E8=BF=85=E6=80=BB=E9=A2=9D?= =?UTF-8?q?=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/small/client/dao/SxDataDao.java | 6 +++++- .../com/small/client/service/imp/SxDataServiceImp.java | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/client/src/main/java/com/small/client/dao/SxDataDao.java b/client/src/main/java/com/small/client/dao/SxDataDao.java index 67727c77..f7ba6a94 100644 --- a/client/src/main/java/com/small/client/dao/SxDataDao.java +++ b/client/src/main/java/com/small/client/dao/SxDataDao.java @@ -625,7 +625,11 @@ public class SxDataDao extends BaseDao{ rmSaleflow.setItemNo(itemNo); rmSaleflow.setSalePrice(unitPrice); rmSaleflow.setSaleQnty(stock_qty); - rmSaleflow.setSaleMoney(productQuantityConsumptionDto.getSaleAmount()); + BigDecimal saleMoney = unitPrice.multiply(stock_qty).setScale(2, RoundingMode.HALF_UP); + if(saleMoney.compareTo(BigDecimal.ZERO)<0){ + saleMoney=saleMoney.multiply(new BigDecimal(-1)); + } + rmSaleflow.setSaleMoney(saleMoney); // rmSaleflow.setSourcePrice(unitPrice); rmSaleflow.setFlownoRand(productQuantityConsumptionDto.getOrderId());//随机子单号 设置网上订单号 if(null!=productQuantityConsumptionDto.getSaleTime()){ diff --git a/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java b/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java index 361f22f9..fefa2910 100644 --- a/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java +++ b/client/src/main/java/com/small/client/service/imp/SxDataServiceImp.java @@ -815,7 +815,15 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService Map productQuantityConsumptionDtoMap=new HashMap<>(); productQuantityConsumptionDtoList.forEach(productQuantityConsumptionDto -> { - productQuantityConsumptionDtoMap.put(productQuantityConsumptionDto.getOrderId()+"-"+productQuantityConsumptionDto.getProductNumber(),productQuantityConsumptionDto); + String key=productQuantityConsumptionDto.getOrderId()+"-"+productQuantityConsumptionDto.getProductNumber(); + if(null!=productQuantityConsumptionDtoMap.get(key)){ + ProductQuantityConsumptionDto oldProductQuantityConsumptionDto=productQuantityConsumptionDtoMap.get(key); + if(productQuantityConsumptionDto.getSaleTime() Date: Fri, 28 Nov 2025 16:12:08 +0800 Subject: [PATCH 51/81] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E5=88=86?= =?UTF-8?q?=E7=B1=BB=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ShopBaseProductCategoryServiceImpl.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java index 651162e3..63a0691a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java @@ -231,11 +231,12 @@ public class ShopBaseProductCategoryServiceImpl extends BaseServiceImpl getCategoryTree() { QueryWrapper queryWrapper = new QueryWrapper<>(); String redisKey = RedisConstant.Product_Cate_Key; + Integer store_id =0; if (getCurrentUser().isStore()) { - Integer store_id = Convert.toInt(getCurrentUser().getStore_id()); - queryWrapper.eq("store_id", store_id); - redisKey = RedisConstant.Product_Cate_Key + ":" + store_id; + store_id = Convert.toInt(getCurrentUser().getStore_id()); } + queryWrapper.eq("store_id", store_id); + redisKey = RedisConstant.Product_Cate_Key + ":" + store_id; List cateTree = Convert.toList(Map.class, redisService.get(redisKey)); if (CollUtil.isNotEmpty(cateTree)) { return cateTree; From a73615f3501b59356bb697b07fb88af50ffd0d42 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sat, 29 Nov 2025 00:44:04 +0800 Subject: [PATCH 52/81] =?UTF-8?q?=E9=80=80=E6=AC=BE=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/pojo/vo/OrderItemPrintVO.java | 5 +- .../mall/common/pojo/vo/OrderPrintVO.java | 121 +++++++++++++++++- .../controller/mobile/LakalaController.java | 7 +- .../order/mapper/ShopOrderReturnMapper.java | 10 ++ .../order/service/ShopOrderReturnService.java | 11 ++ .../impl/ShopOrderReturnServiceImpl.java | 24 ++++ .../mapper/order/ShopOrderBaseMapper.xml | 32 ----- .../mapper/order/ShopOrderReturnMapper.xml | 91 +++++++++++++ .../resources/templates/order_printer.txt | 42 ++++++ .../templates/refund_order_printer.txt | 52 ++++---- 10 files changed, 328 insertions(+), 67 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java index 883e2b20..bf565b03 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderItemPrintVO.java @@ -16,12 +16,15 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +/** + * 订单商品详情打印对象 + */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor -@ApiModel(value = "订单商品打印对象", description = "订单商品打印对象") +@ApiModel(value = "订单商品详情打印对象", description = "订单商品详情打印对象") public class OrderItemPrintVO implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "商品名") diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java index 774f1c6a..9c7db24a 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java @@ -1,13 +1,14 @@ package com.suisung.mall.common.pojo.vo; import io.swagger.annotations.ApiModel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; import lombok.experimental.Accessors; import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; /** * 退货单打印对象 @@ -17,9 +18,121 @@ import java.io.Serializable; @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor +@Builder @ApiModel(value = "(退款)订单主信息打印对象", description = "(退款)订单主信息打印对象") public class OrderPrintVO implements Serializable { private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "订单编号") + private String order_id; + + @ApiModelProperty(value = "退单编号") + private String return_id; + + @ApiModelProperty(value = "店铺名称") + private String store_name; + + @ApiModelProperty(value = "店铺电话") + private String store_tel; + + @ApiModelProperty(value = "(配送)取单号") + @Builder.Default + private String order_pickup_num_str = "#0000000"; + + @ApiModelProperty(value = "退款订单编号") + private String order_message; + + @ApiModelProperty(value = "支付时间") + private Date payment_time; + + @ApiModelProperty(value = "商品总件数") + private Integer order_items_count; + + @ApiModelProperty(value = "商品总类数") + private Integer order_product_amount; + + @ApiModelProperty(value = "订单配送费") + private BigDecimal order_shipping_fee; + + @ApiModelProperty(value = "订单来源") + @Builder.Default + private String order_channel_name = "微信小程序"; + + @ApiModelProperty(value = "支付方式") + @Builder.Default + private String payment_type_name = "微信支付"; + + @ApiModelProperty(value = "配送渠道") + @Builder.Default + private String deliver_type_name = "顺丰同城"; + + @ApiModelProperty(value = "打包费") + private BigDecimal packing_fee; + + @ApiModelProperty(value = "会员优惠权益金额") + private BigDecimal basic_rights; + + @ApiModelProperty(value = "实付金额") + private BigDecimal order_payment_amount; + + @ApiModelProperty(value = "退款金额") + private BigDecimal return_refund_amount; + + @ApiModelProperty(value = "订单状态(LIST):2011-待订单审核;2013-待财务审核;2020-待配货/待出库审核;2030-待发货;2040-已发货/待收货确认;2060-已完成/已签收;2070-已取消/已作废;") + private String order_state; + + @ApiModelProperty(value = "下单时买家退货留言") + private String return_buyer_message; + + @ApiModelProperty(value = "下单时商家留言") + private String seller_message; + + @ApiModelProperty(value = "买家退货留言") + private String return_store_message; + + @ApiModelProperty(value = "申请退款时间") + private Date return_add_time; + + @ApiModelProperty(value = "退款完成时间") + private Date return_finish_time; + + @ApiModelProperty(value = "预订单状态") + private Integer booking_state; + + @ApiModelProperty(value = "预订单开始时间") + private Date booking_begin_time; + + @ApiModelProperty(value = "退货类型(ENUM): 0-不用退货;1-需要退货") + @Builder.Default + private String return_flag_str = "原路返回"; + + @ApiModelProperty(value = "卖家处理状态(ENUM): 3100-【客户】提交退单;3105-退单审核;3110-收货确认;3115-退款确认;3120-【客户】收款确认;3125-完成退款;3130-商家拒绝退货;3135-买家取消退款") + private String return_state; + + @ApiModelProperty(value = "买方用户名") + private String buyer_user_name; + + @ApiModelProperty(value = "退款人手机号") + private String return_tel; + + @ApiModelProperty(value = "收货联系电话") + private String da_mobile; + + @ApiModelProperty(value = "收货省份") + private String da_province; + + @ApiModelProperty(value = "收货城市") + private String da_city; + + @ApiModelProperty(value = "收货详细地址") + private String da_address; + + @ApiModelProperty(value = "(店长)收银员") + @Builder.Default + private String cashier = "收银员"; + + @ApiModelProperty(value = "订单商品详情打印对象列表") + private List orderItemPrintVOList; + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 265453ad..7d5f3e00 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -14,7 +14,6 @@ import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.service.impl.BaseControllerImpl; import com.suisung.mall.shop.lakala.service.LakalaApiService; import com.suisung.mall.shop.lakala.service.LklLedgerEcService; -import com.suisung.mall.shop.lakala.service.LklLedgerReceiverService; import com.suisung.mall.shop.library.service.LibraryProductService; import com.suisung.mall.shop.message.service.MqMessageService; import com.suisung.mall.shop.message.service.PushMessageService; @@ -83,8 +82,6 @@ public class LakalaController extends BaseControllerImpl { @Resource private LklLedgerEcService lklLedgerEcService; - @Resource - private LklLedgerReceiverService lklLedgerReceiverService; @ApiOperation(value = "测试案例", notes = "测试案例") @RequestMapping(value = "/testcase", method = RequestMethod.POST) @@ -94,7 +91,9 @@ public class LakalaController extends BaseControllerImpl { // return lakalaApiService.ewalletWithDrawNotify(null, paramsJSON.getStr("a"), paramsJSON.getStr("b")); - return lakalaApiService.tradeQuery(paramsJSON.getInt("storeId"), paramsJSON.getStr("orderId")); + // return lakalaApiService.tradeQuery(paramsJSON.getInt("storeId"), paramsJSON.getStr("orderId")); + + return JSONUtil.parseObj(shopOrderReturnService.fetchReturnOrderPrintInfo("", "FX_20251127_9")); } @ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderReturnMapper.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderReturnMapper.java index a0055868..c6f2c988 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderReturnMapper.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderReturnMapper.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.suisung.mall.common.modules.order.ShopOrderReturn; +import com.suisung.mall.common.pojo.vo.OrderPrintVO; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; @@ -30,4 +31,13 @@ public interface ShopOrderReturnMapper extends BaseMapper { List> statisticCountSeller(@Param("end") Date end, @Param("days") int days, @Param("store_id") int store_id); IPage getReturnGroupByOrderId(Page page, @Param("map") Map params); + + /** + * 根据退货订单id获取退货订单打印信息 + * + * @param orderId + * @param returnId + * @return + */ + OrderPrintVO fetchReturnOrderPrintInfo(@Param("orderId") String orderId, @Param("returnId") String returnId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java index 211916bc..e00dcb59 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java @@ -7,6 +7,7 @@ import com.suisung.mall.common.modules.order.ShopOrderItem; import com.suisung.mall.common.modules.order.ShopOrderReturn; import com.suisung.mall.common.modules.order.ShopOrderReturnItem; import com.suisung.mall.common.modules.product.ShopProductIndex; +import com.suisung.mall.common.pojo.vo.OrderPrintVO; import com.suisung.mall.core.web.service.IBaseService; import com.suisung.mall.shop.order.vo.OrderReturnInputVo; @@ -225,4 +226,14 @@ public interface ShopOrderReturnService extends IBaseService { CommonResult doRefundForMch(JSONObject params); + /** + * 根据退货订单id获取退货订单打印信息 + * + * @param orderId + * @param returnId + * @return + */ + OrderPrintVO fetchReturnOrderPrintInfo(String orderId, String returnId); + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index e6425ea0..19ef4f9c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -35,6 +35,7 @@ import com.suisung.mall.common.modules.product.ShopProductInfo; import com.suisung.mall.common.modules.product.ShopProductItem; import com.suisung.mall.common.modules.store.ShopStoreBase; import com.suisung.mall.common.modules.store.ShopStoreShippingAddress; +import com.suisung.mall.common.pojo.vo.OrderPrintVO; import com.suisung.mall.common.service.MessageService; import com.suisung.mall.common.utils.*; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; @@ -3008,6 +3009,29 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl - - diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml index 90471d81..3cfd21a3 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml @@ -86,4 +86,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mall-shop/src/main/resources/templates/order_printer.txt b/mall-shop/src/main/resources/templates/order_printer.txt index aca6a23e..2b4ec44c 100644 --- a/mall-shop/src/main/resources/templates/order_printer.txt +++ b/mall-shop/src/main/resources/templates/order_printer.txt @@ -51,6 +51,48 @@ 收银员:李小璐
+格式化带变量模版: +<#if is_booking_order>【预约订单】
+${store_name}
+--------------------------------
+#${order_pickup_num_str}
+买家备注:${order_message!'-'}
+配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}
+--------------------------------
+订单编号:${order_id}
+订单来源:微信小程序
+支付方式:微信支付
+配送来源:顺丰同城
+付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
+--------------------------------
+商品名称 数量 金额
+--------------------------------
+<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
+<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
+<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
+
+ +--------------------------------
+商品总件数:${order_items_count!0}
+商品总额:¥${order_product_amount?string('0.00')}
+运费:¥${order_shipping_fee?string('0.00')}
+<#if packing_fee?? && (packing_fee > 0)>打包费:¥${packing_fee?string('0.00')}
+优惠金额:-¥${(quanyi!0)?string('0.00')}
+实付金额:¥${order_payment_amount?string('0.00')}
+<#if seller_message?default("")?trim?length gt 1> +--------------------------------
+商家备注:${seller_message!'-'}
+ +--------------------------------
+收货人:${buyer_user_name!''}
+收货人手机:${da_mobile!'-'}
+收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}
+--------------------------------
+门店:${store_name}
+门店电话:${store_tel!'-'}
+收银员:${cashier!'店长'}
+ + 格式化的示例: 小发同城
--------------------------------
#00019232
买家备注:不用敲门,放在门口旁边的外卖箱,打个电话告知送达就行,谢谢!!!
配送时间:2024-10-25 14:00-14:30
--------------------------------
订单编号:ES20231026111444527685
订单来源:微信小程序
支付方式:微信支付
配送来源:顺丰同城
付款时间:2024-10-25 14:00:23
--------------------------------
商品名称 数量 金额
--------------------------------
可口可乐CocaC x110 8100.45
ola经典美味汽水1.2
5L/瓶
6970448170051
排骨约350g(默 1 150.13
认砍小块)
6970448170053
新鲜虫草花1包约2 x11 4.01
00g 韭菜1000g 鸡蛋
2003克
6970448170054
冰红茶风味饮料 1 13.24
6970448170055
--------------------------------
商品总件数:3
商品总额:¥18.7
押金:¥500
运费:¥5.54
会员权益:-¥50
秒杀:-¥100
实付金额:¥428.9元
--------------------------------
商家备注:老顾客赠送一箱牛奶;玻璃瓶包装轻拿轻放!
--------------------------------
收货人:张三
收货人手机:13128778765
收货地址:北京市朝阳区朝阳路朝阳人民小区1号楼1栋1101
--------------------------------
门店:岛内价生活超市
门店电话:13665822542
收银员:李小璐
diff --git a/mall-shop/src/main/resources/templates/refund_order_printer.txt b/mall-shop/src/main/resources/templates/refund_order_printer.txt index a5d13886..43bcf846 100644 --- a/mall-shop/src/main/resources/templates/refund_order_printer.txt +++ b/mall-shop/src/main/resources/templates/refund_order_printer.txt @@ -41,41 +41,41 @@ 修改后的模版 -小发同城
+ +用户退款订单
+${store_name}
--------------------------------
-#00019232
-退款原因:不用敲门,放在门口旁边的外卖箱,打个电话告知送达就行,谢谢!!!
-配送时间:2024-10-25 14:00-14:30
+#${order_pickup_num_str}
+退款原因:${return_buyer_message!'-'}
+配送时间:${payment_time}(之后20-30分钟)
--------------------------------
-订单编号:ES20231026111444527685
-退单编号:ES20231026111444527685
-订单来源:微信小程序
-支付方式:微信支付
-配送来源:顺丰同城
-付款时间:2024-10-25 14:00:23
-申请退款:2024-10-27 14:05:23
-确认退款:2024-10-27 14:8:23
+订单编号:${order_id}
+退单编号:${return_id}
+订单来源:${order_channel_name!'微信小程序'}
+支付方式:${payment_type_name!'微信支付'}
+配送来源:${deliver_type_name!'顺丰同城'}
+付款时间:${payment_time}
+申请退款:${return_add_time}
+确认退款:${return_finish_time}
--------------------------------
******* 退款商品 ******
--------------------------------
-可口可乐CocaC x110 8100.45
-ola经典美味汽水1.2
-5L/瓶
-6970448170051
-排骨约350g(默 1 150.13
-认砍小块)
-6970448170053
+<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
-实付金额:¥428.9元
-申请退款:¥32.7
-退款方式:仅退款
-商家审批备注:商家发货少了
+实付金额:¥${order_payment_amount?string('0.00')}元
+配送费:¥${order_shipping_fee?string('0.00')}元
+申请退款:¥${return_refund_amount?string('0.00')}
+退款方式:${return_flag_str}
+商家审批备注:${return_store_message!'-'}
--------------------------------
-会员名称:张三
-会员手机:13128778765
+会员名称:${buyer_user_name!'微信用户'}
+会员手机:${return_tel!'-'}
--------------------------------
-操作员:李小明
+操作员:${cashier!'-'}
原模版: ${store_name}
--------------------------------
#${order_pickup_num_str}
买家备注:${order_message!'-'}
配送时间:${delivery_time}
--------------------------------
订单编号:${order_id}
订单来源:微信小程序
支付方式:微信支付
配送来源:顺丰同城
付款时间:${payment_time}
--------------------------------
商品名称 数量 金额
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
商品总件数:${order_items_count!0}
商品总额:¥${order_product_amount?string('0.00')}
押金:¥${(yajin!0)?string('0.00')}
运费:¥${order_shipping_fee?string('0.00')}
会员权益:-¥${(quanyi!0)?string('0.00')}
秒杀:-¥${(miaosha!0)?string('0.00')}
实付金额:¥${order_payment_amount?string('0.00')}
<#if seller_message?default("")?trim?length gt 1>--------------------------------
商家备注:${seller_message!'---'}
--------------------------------
收货人:${buyer_user_name!''}
收货人手机:${store_tel!''}
收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}
--------------------------------
门店:${store_name}
门店电话:${store_tel!'-'}
收银员:${cashier!'-'}
+ +带参模版: +用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time}(之后20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time}
申请退款:${return_add_time}
确认退款:${return_finish_time}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}
From 1d328b38f7eaed5848c0362c707432324f0d27ba Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sat, 29 Nov 2025 02:27:02 +0800 Subject: [PATCH 53/81] =?UTF-8?q?=E9=80=80=E6=AC=BE=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/pojo/vo/OrderPrintVO.java | 5 +- .../mall/common/utils/FreeMakerUtils.java | 6 +- .../controller/mobile/LakalaController.java | 5 +- .../service/ShopStorePrinterService.java | 9 ++ .../impl/ShopStorePrinterLogServiceImpl.java | 51 +++++-- .../impl/ShopStorePrinterServiceImpl.java | 139 +++++++++++++++++- .../mapper/order/ShopOrderReturnMapper.xml | 3 +- .../templates/refund_order_printer.txt | 10 +- 8 files changed, 202 insertions(+), 26 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java index 9c7db24a..d1f166ab 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java @@ -29,6 +29,9 @@ public class OrderPrintVO implements Serializable { @ApiModelProperty(value = "退单编号") private String return_id; + @ApiModelProperty(value = "店铺Id") + private Integer store_id; + @ApiModelProperty(value = "店铺名称") private String store_name; @@ -132,7 +135,7 @@ public class OrderPrintVO implements Serializable { private String cashier = "收银员"; @ApiModelProperty(value = "订单商品详情打印对象列表") - private List orderItemPrintVOList; + private List order_items; } diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java index 90877d3c..955df822 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java @@ -39,7 +39,7 @@ public class FreeMakerUtils { * @throws IOException * @throws TemplateException */ - public static String processTemplate(Configuration configuration, String templateName, String templateValue, Map binding) { + public static String processTemplate(Configuration configuration, String templateName, String templateValue, Object binding) { StringWriter stringWriter = new StringWriter(); try { Template template = new Template(templateName, templateValue, configuration); @@ -63,4 +63,8 @@ public class FreeMakerUtils { public static String processTemplate(String templateName, String templateValue, Map binding) { return processTemplate(stringTempConfiguration(), templateName, templateValue, binding); } + + public static String processTemplate(String templateName, String templateValue, Object binding) { + return processTemplate(stringTempConfiguration(), templateName, templateValue, binding); + } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 7d5f3e00..43ee78a6 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -20,6 +20,7 @@ import com.suisung.mall.shop.message.service.PushMessageService; import com.suisung.mall.shop.order.service.ShopOrderBaseService; import com.suisung.mall.shop.order.service.ShopOrderReturnService; import com.suisung.mall.shop.sfexpress.service.SFExpressApiService; +import com.suisung.mall.shop.store.service.ShopStorePrinterService; import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -77,7 +78,7 @@ public class LakalaController extends BaseControllerImpl { @Lazy @Resource - private LakalaApiService lakalaApiService; + private ShopStorePrinterService shopStorePrinterService; @Resource private LklLedgerEcService lklLedgerEcService; @@ -93,7 +94,7 @@ public class LakalaController extends BaseControllerImpl { // return lakalaApiService.tradeQuery(paramsJSON.getInt("storeId"), paramsJSON.getStr("orderId")); - return JSONUtil.parseObj(shopOrderReturnService.fetchReturnOrderPrintInfo("", "FX_20251127_9")); + return shopStorePrinterService.printShopStoreReturnOrder(paramsJSON.getStr("orderId"), paramsJSON.getStr("returnId")); } @ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java index 833c0e35..7aa53d9f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java @@ -80,6 +80,15 @@ public interface ShopStorePrinterService extends IBaseService */ Boolean printShopStoreOrder(Integer storeId, String orderId); + /** + * 退货成功后,立即打印门店的退货信息 + * + * @param orderId + * @param returnId + * @return + */ + Boolean printShopStoreReturnOrder(String orderId, String returnId); + /** * 获取店铺所有有效打印机 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java index 413bd440..8257424e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java @@ -5,11 +5,9 @@ import cn.hutool.core.util.StrUtil; import com.suisung.mall.common.modules.store.ShopStorePrinterLog; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.store.mapper.ShopStorePrinterLogMapper; -import com.suisung.mall.shop.store.mapper.ShopStorePrinterMapper; import com.suisung.mall.shop.store.service.ShopStorePrinterLogService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -19,41 +17,70 @@ import java.util.List; public class ShopStorePrinterLogServiceImpl extends BaseServiceImpl implements ShopStorePrinterLogService { private static final Logger logger = LoggerFactory.getLogger(ShopStorePrinterLogServiceImpl.class); - @Autowired - private ShopStorePrinterMapper shopStorePrinterMapper; @Override public Boolean insertShopStorePrinterLog(ShopStorePrinterLog record) { + // 参数校验 if (record == null) { + logger.warn("插入打印日志失败:记录为空"); return false; } + // 必要字段校验 if (record.getStore_id() == null || StrUtil.isBlank(record.getOrder_id()) || StrUtil.isBlank(record.getTemplate_value()) || StrUtil.isBlank(record.getPrint_content())) { + logger.warn("插入打印日志失败:必要字段缺失,storeId={}, orderId={}", + record.getStore_id(), record.getOrder_id()); return false; } - return add(record); + try { + // 执行插入操作 + return add(record); + } catch (Exception e) { + logger.error("插入打印日志时发生异常,storeId={}, orderId={}", + record.getStore_id(), record.getOrder_id(), e); + return false; + } } + @Override public void insertShopStorePrinterLogBatch(List records) { + // 参数校验 if (CollUtil.isEmpty(records)) { + logger.debug("批量插入打印日志失败:记录列表为空"); return; } - for (ShopStorePrinterLog record : records) { - if (record.getStore_id() == null || - StrUtil.isBlank(record.getOrder_id()) || - StrUtil.isBlank(record.getTemplate_value()) || - StrUtil.isBlank(record.getPrint_content())) { - continue; + try { + for (ShopStorePrinterLog record : records) { + // 单条记录校验 + if (record == null) { + logger.warn("批量插入打印日志跳过:记录为空"); + continue; + } + + if (record.getStore_id() == null || + StrUtil.isBlank(record.getOrder_id()) || + StrUtil.isBlank(record.getTemplate_value()) || + StrUtil.isBlank(record.getPrint_content())) { + logger.warn("批量插入打印日志跳过:必要字段缺失,storeId={}, orderId={}", + record.getStore_id(), record.getOrder_id()); + continue; + } + + // 执行插入操作 + add(record); } - add(record); + logger.debug("批量插入打印日志完成,共处理 {} 条记录", records.size()); + } catch (Exception e) { + logger.error("批量插入打印日志时发生异常,记录数: {}", records.size(), e); } } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java index 1efc3c6a..a1debf34 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java @@ -14,13 +14,15 @@ import com.suisung.mall.common.domain.UserDto; import com.suisung.mall.common.modules.store.ShopStorePrinter; import com.suisung.mall.common.modules.store.ShopStorePrinterLog; import com.suisung.mall.common.modules.store.ShopStorePrinterTemplate; +import com.suisung.mall.common.pojo.vo.OrderItemPrintVO; +import com.suisung.mall.common.pojo.vo.OrderPrintVO; import com.suisung.mall.common.pojo.vo.ShopStorePrinterVO; import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.common.utils.FreeMakerUtils; import com.suisung.mall.common.utils.JsonUtil; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.order.service.ShopOrderBaseService; -import com.suisung.mall.shop.order.service.impl.ShopOrderInfoServiceImpl; +import com.suisung.mall.shop.order.service.ShopOrderReturnService; import com.suisung.mall.shop.store.mapper.ShopStorePrinterMapper; import com.suisung.mall.shop.store.service.ShopStorePrinterLogService; import com.suisung.mall.shop.store.service.ShopStorePrinterService; @@ -49,15 +51,13 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl + * 该方法通过调用飞鹅打票机接口,完成指定订单的退货小票打印功能。主要流程包括: + * 1. 校验订单号是否合法; + * 2. 获取订单及店铺相关信息; + * 3. 查询对应店铺绑定的打印机列表与打印模板; + * 4. 渲染打印内容并发送至所有绑定的打印机; + * 5. 记录打印日志。 + *

+ * + * @param orderId 订单编号,不能为空 + * @param returnId 退货单编号,用于标识具体的退货记录 + * @return 打印操作是否成功,成功返回 true,否则返回 false + */ + @Override + public Boolean printShopStoreReturnOrder(String orderId, String returnId) { + logger.debug("#### 调用飞鹅打票机的打印退款订单操作开始 ####"); + + // 参数校验 + if (StrUtil.isBlank(returnId)) { + logger.error("退款订单为空,无法打印小票。"); + return false; + } + + try { + // 获取打印的订单信息,并检查订单是否存在且已支付 + OrderPrintVO binding = shopOrderReturnService.fetchReturnOrderPrintInfo(orderId, returnId); + if (binding == null) { + logger.error("退款订单Id{}信息无法获取,无法打印小票。", returnId); + return false; + } + + logger.debug("退款订单信息:{}", binding); + + orderId = binding.getOrder_id(); + Integer storeId = binding.getStore_id(); + if (CheckUtil.isEmpty(storeId) || CheckUtil.isEmpty(orderId)) { + logger.warn("订单Id:{},店铺ID:{}为空,无法打印小票。", orderId, storeId); + return false; + } + + // 查询店铺配置的打印机列表 + List printerList = selectPrinterList(storeId); + if (CollUtil.isEmpty(printerList)) { + // 店铺没有打印机,不再继续执行打印逻辑 + logger.error("店铺{}未添加打票机,无法打印小票。", storeId); + return false; + } + + // 获取适用于退货场景的打印模板 + ShopStorePrinterTemplate template = shopStorePrinterTemplateService.getShopStorePrinterTemplateInner(storeId, StateCode.PRINTER_TEMP_CATE_REFUND); + if (template == null || StrUtil.isBlank(template.getTemplate_name()) || StrUtil.isBlank(template.getTemplate_value())) { + // 模板缺失或无效,终止打印流程 + logger.error("店铺{}未添加打票机打印模版,无法打印小票。", storeId); + return false; + } + + // 重要:重构实体类,处理标题,数量,价格适应长度 + List orderItems = binding.getOrder_items(); + if (CollUtil.isEmpty(orderItems)) { + logger.error("订单{}商品信息为空,无法打印小票。", orderId); + return false; + } + + List rebuiltItems = new ArrayList<>(orderItems.size()); + for (OrderItemPrintVO item : orderItems) { + if (item != null) { + rebuiltItems.add(item.rebuild()); + } + } + binding.setOrder_items(rebuiltItems); + + // 使用 FreeMarker 模板引擎渲染实际要打印的内容 + String printContent = FreeMakerUtils.processTemplate(template.getTemplate_name(), template.getTemplate_value(), binding); + if (StrUtil.isBlank(printContent)) { + logger.error("订单{}信息模版渲染异常,无法打印小票。", orderId); + return false; + } + logger.debug("打印内容长度:{}", printContent.length()); + + // 提取所有打印机设备序列号,准备批量打印 + List printerSnList = new ArrayList<>(printerList.size()); + for (ShopStorePrinter printer : printerList) { + if (printer != null && StrUtil.isNotBlank(printer.getPrinter_sn())) { + printerSnList.add(printer.getPrinter_sn()); + } + } + + if (CollUtil.isEmpty(printerSnList)) { + logger.error("订单{}没有有效的打印机设备,无法打印小票。", orderId); + return false; + } + + // 向飞鹅打票机发送打印任务 + List> respList = feieUtil.printContentByList(printerSnList, printContent); + if (CollUtil.isEmpty(respList)) { + // 所有打印机均未能响应,视为失败 + logger.error("订单{}信息打印,调用飞鹅打印机打印失败。", orderId); + return false; + } + + // 遍历每台打印机的响应结果,记录打印日志 + for (Pair respSn : respList) { + if (respSn != null) { + // 构造并保存本次打印的日志记录 + ShopStorePrinterLog shopStorePrinterLog = new ShopStorePrinterLog( + template.getCategory(), + storeId, + orderId, + template.getTemplate_id(), + template.getTemplate_value(), + JsonUtil.object2json(binding), + printContent, + respSn.getSecond(), + respSn.getFirst() + ); + shopStorePrinterLogService.insertShopStorePrinterLog(shopStorePrinterLog); + } + } + + logger.debug("#### 调用飞鹅打票机的打印操作结束 ####"); + return true; + + } catch (Exception e) { + logger.error("打印退货订单小票时发生异常,订单ID: {}, 退货单ID: {}", orderId, returnId, e); + return false; + } + } + + @Override public List selectPrinterList(Integer storeId) { if (storeId == null) { diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml index 3cfd21a3..8ae0e6c9 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml @@ -92,6 +92,7 @@ + @@ -123,7 +124,7 @@ - + diff --git a/mall-shop/src/main/resources/templates/refund_order_printer.txt b/mall-shop/src/main/resources/templates/refund_order_printer.txt index 43bcf846..f4aa09e7 100644 --- a/mall-shop/src/main/resources/templates/refund_order_printer.txt +++ b/mall-shop/src/main/resources/templates/refund_order_printer.txt @@ -47,16 +47,16 @@ --------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
-配送时间:${payment_time}(之后20-30分钟)
+配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(之后20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
-付款时间:${payment_time}
-申请退款:${return_add_time}
-确认退款:${return_finish_time}
+付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
+申请退款:${return_add_time?string('yyyy-MM-dd HH:mm:ss')}
+确认退款:${return_finish_time?string('yyyy-MM-dd HH:mm:ss')}
--------------------------------
******* 退款商品 ******
--------------------------------
@@ -78,4 +78,4 @@ ${store_name}
--------------------------------
#${order_pickup_num_str}
买家备注:${order_message!'-'}
配送时间:${delivery_time}
--------------------------------
订单编号:${order_id}
订单来源:微信小程序
支付方式:微信支付
配送来源:顺丰同城
付款时间:${payment_time}
--------------------------------
商品名称 数量 金额
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
商品总件数:${order_items_count!0}
商品总额:¥${order_product_amount?string('0.00')}
押金:¥${(yajin!0)?string('0.00')}
运费:¥${order_shipping_fee?string('0.00')}
会员权益:-¥${(quanyi!0)?string('0.00')}
秒杀:-¥${(miaosha!0)?string('0.00')}
实付金额:¥${order_payment_amount?string('0.00')}
<#if seller_message?default("")?trim?length gt 1>--------------------------------
商家备注:${seller_message!'---'}
--------------------------------
收货人:${buyer_user_name!''}
收货人手机:${store_tel!''}
收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}
--------------------------------
门店:${store_name}
门店电话:${store_tel!'-'}
收银员:${cashier!'-'}
带参模版: -用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time}(之后20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time}
申请退款:${return_add_time}
确认退款:${return_finish_time}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}
+用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
申请退款:${return_add_time?string('yyyy-MM-dd HH:mm:ss')}
确认退款:${return_finish_time?string('yyyy-MM-dd HH:mm:ss')}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}
From d9bb03770ac0f9c9f418b9147e9d136510ba0d26 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Sat, 29 Nov 2025 10:38:19 +0800 Subject: [PATCH 54/81] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=88=86=E7=B1=BB=E6=96=B0=E5=A2=9E=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=B7=BB=E5=8A=A0=E5=88=86=E7=B1=BB=E7=9A=84=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShopBaseProductCategoryController.java | 16 +++++-- .../ShopBaseProductCategoryService.java | 4 ++ .../ShopBaseProductCategoryServiceImpl.java | 42 +++++++++++++++++++ .../service/impl/SyncBaseThirdSxAbstract.java | 11 ++++- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/controller/admin/ShopBaseProductCategoryController.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/controller/admin/ShopBaseProductCategoryController.java index 9dac3ce7..612fa1c4 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/controller/admin/ShopBaseProductCategoryController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/controller/admin/ShopBaseProductCategoryController.java @@ -1,6 +1,7 @@ package com.suisung.mall.shop.base.controller.admin; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.base.ShopBaseProductCategory; @@ -10,10 +11,7 @@ import com.suisung.mall.shop.base.service.ShopBaseProductCategoryService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser; @@ -168,5 +166,15 @@ public class ShopBaseProductCategoryController { return CommonResult.success(shopBaseProductCategoryService.tree(queryWrapper)); } + /** + * 新增优化 + * @return + */ + @ApiOperation(value = "商品分类表-新增优化", notes = "商品分类表-新增优化") + @RequestMapping(value = "/simpleAdd", method = {RequestMethod.POST}) + public CommonResult simpleAdd(@RequestBody JSONArray jsonArray) { + return CommonResult.success(shopBaseProductCategoryService.simpleAdd(jsonArray)); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseProductCategoryService.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseProductCategoryService.java index fbcc6997..33108508 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseProductCategoryService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseProductCategoryService.java @@ -1,7 +1,9 @@ package com.suisung.mall.shop.base.service; +import cn.hutool.json.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.domain.UserDto; import com.suisung.mall.common.modules.admin.ElTree; import com.suisung.mall.common.modules.base.ShopBaseProductCategory; @@ -151,4 +153,6 @@ public interface ShopBaseProductCategoryService extends IBaseService tree(QueryWrapper queryWrapper) { List list = find(queryWrapper); @@ -1279,4 +1290,35 @@ public class ShopBaseProductCategoryServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id",Integer.valueOf(storeId)); + queryWrapper.eq("brand_name","其它品牌"); + List shopBaseProductBrands=productBrandService.list(queryWrapper); + if(CollectionUtil.isEmpty(shopBaseProductBrands)){ + ShopBaseProductBrand shopBaseProductBrand=new ShopBaseProductBrand(); + shopBaseProductBrand.setBrand_name("其它品牌"); + shopBaseProductBrand.setBrand_desc("其它品牌"); + productBrandService.saveOrUpdateBrand(shopBaseProductBrand); + } + List shopBaseProductCategories = JSONUtil.toList(jsonArray, ShopBaseProductCategory.class); + syncThirdDataService.baseSaveOrUpdateShopBaseProductCategoryBatch(shopBaseProductCategories,jsonArray,storeId); + String redisKey = RedisConstant.Product_Cate_Key + ":" + storeId; + redisService.del(redisKey); + }else{ + throw new ApiException("权限不足"); + } + + return null; + } + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java index 70afc2aa..7342afea 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java @@ -15,6 +15,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.suisung.mall.common.api.ResultCode; import com.suisung.mall.common.api.StateCode; import com.suisung.mall.common.constant.CommonConstant; +import com.suisung.mall.common.domain.UserDto; import com.suisung.mall.common.enums.DicEnum; import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.feignService.AccountService; @@ -35,6 +36,7 @@ import com.suisung.mall.common.modules.store.ShopStoreBase; import com.suisung.mall.common.pojo.dto.LibraryProductDTO; import com.suisung.mall.common.pojo.req.SyncThirdMemberReq; import com.suisung.mall.common.pojo.res.ThirdApiRes; +import com.suisung.mall.common.utils.ContextUtil; import com.suisung.mall.common.utils.DateTimeUtils; import com.suisung.mall.common.utils.I18nUtil; import com.suisung.mall.common.utils.StringUtils; @@ -51,6 +53,7 @@ import com.suisung.mall.shop.sixun.dto.SxGoosModel; import com.suisung.mall.shop.store.service.ShopStoreActivityBaseService; import com.suisung.mall.shop.store.service.ShopStoreBaseService; import org.apache.commons.lang3.math.NumberUtils; +import org.hibernate.validator.internal.util.stereotypes.Lazy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -71,6 +74,7 @@ public abstract class SyncBaseThirdSxAbstract{ private final Logger logger = LoggerFactory.getLogger(SyncBaseThirdSxAbstract.class); @Autowired private ShopBaseProductBrandService productBrandService; + @Lazy @Autowired private ShopBaseProductCategoryService productCategoryService; @Autowired @@ -130,6 +134,11 @@ public abstract class SyncBaseThirdSxAbstract{ public int baseSaveOrUpdateShopBaseProductCategoryBatch(List list ,JSONArray categoryListJSON, String storeId){ int count = 0; + UserDto userDto=ContextUtil.getCurrentUser(); + Integer dataSource=1; + if(userDto==null){ + dataSource=2; + } List productTypeList = new ArrayList<>(); Map productTypeListMap=new HashMap<>(); for (int i = 0; i < list.size(); i++) { @@ -138,7 +147,7 @@ public abstract class SyncBaseThirdSxAbstract{ continue; } list.get(i).setStore_id(storeId); // app 记录传进来 - list.get(i).setData_source(2); // 思迅数据来源 + list.get(i).setData_source(dataSource); // 思迅数据来源 list.get(i).setCategory_is_enable(1); JSONObject o = (JSONObject) categoryListJSON.get(i); From b4e2b927304b5ab1941b3876559e6b716507504c Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Sat, 29 Nov 2025 10:38:30 +0800 Subject: [PATCH 55/81] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=88=86=E7=B1=BB=E6=96=B0=E5=A2=9E=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=B7=BB=E5=8A=A0=E5=88=86=E7=B1=BB=E7=9A=84=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E6=80=A7-=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/shop/dev/20251129_ddl.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 sql/shop/dev/20251129_ddl.sql diff --git a/sql/shop/dev/20251129_ddl.sql b/sql/shop/dev/20251129_ddl.sql new file mode 100644 index 00000000..91ce46fe --- /dev/null +++ b/sql/shop/dev/20251129_ddl.sql @@ -0,0 +1 @@ +INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-base-product-category/simpleAdd', 'index', 'master', '', '0', '/admin/shop/shop-base-product-category/simpleAdd','分类新增-简化版'); \ No newline at end of file From 24a9def0129168192c3c925bf27f8a627cf3d49b Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Sat, 29 Nov 2025 11:34:24 +0800 Subject: [PATCH 56/81] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=88=86=E7=B1=BB=E6=96=B0=E5=A2=9E=EF=BC=8C=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ShopBaseProductCategoryServiceImpl.java | 9 +++++++++ .../shop/sync/service/impl/SyncBaseThirdSxAbstract.java | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java index 6828e546..e2a16196 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseProductCategoryServiceImpl.java @@ -1310,6 +1310,15 @@ public class ShopBaseProductCategoryServiceImpl extends BaseServiceImpl shopBaseProductCategories = JSONUtil.toList(jsonArray, ShopBaseProductCategory.class); + //校验 + for (ShopBaseProductCategory shopBaseProductCategory : shopBaseProductCategories) { + if(StringUtils.isEmpty(shopBaseProductCategory.getCategory_name())){ + throw new ApiException("存在分类为空的值"); + } + if(StringUtils.isEmpty(shopBaseProductCategory.getCategory_image())){ + shopBaseProductCategory.setCategory_image("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/media/media/plantform/20250906/b93a9751b35a49fca6cf979829230868.png"); + } + } syncThirdDataService.baseSaveOrUpdateShopBaseProductCategoryBatch(shopBaseProductCategories,jsonArray,storeId); String redisKey = RedisConstant.Product_Cate_Key + ":" + storeId; redisService.del(redisKey); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java index 7342afea..36814cc1 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/service/impl/SyncBaseThirdSxAbstract.java @@ -148,8 +148,9 @@ public abstract class SyncBaseThirdSxAbstract{ } list.get(i).setStore_id(storeId); // app 记录传进来 list.get(i).setData_source(dataSource); // 思迅数据来源 - list.get(i).setCategory_is_enable(1); - + if(null== list.get(i).getCategory_is_enable()){ + list.get(i).setCategory_is_enable(1); + } JSONObject o = (JSONObject) categoryListJSON.get(i); ShopBaseProductType productType=new ShopBaseProductType(); productType.setType_is_draft(1);//发布 From 655998c805ee218da31191599d42e2d0b27c132f Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sat, 29 Nov 2025 15:33:55 +0800 Subject: [PATCH 57/81] =?UTF-8?q?=E5=BC=82=E6=AD=A5=E9=9D=9E=E9=98=BB?= =?UTF-8?q?=E5=A1=9E=20=E7=A7=92=E6=95=B0=20=E5=A2=9E=E5=8A=A0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/common/constant/MqConstant.java | 1 + .../service/impl/MqMessageServiceImpl.java | 18 ------------------ .../shop/order/listener/MessageListener.java | 1 - .../order/listener/OrderPayedListener.java | 3 +-- .../service/impl/ShopOrderBaseServiceImpl.java | 10 +++++----- .../impl/ShopStorePrinterServiceImpl.java | 8 +++++--- .../ShopStorePrinterTemplateServiceImpl.java | 3 +++ .../templates/refund_order_printer.txt | 2 +- 8 files changed, 16 insertions(+), 30 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/constant/MqConstant.java b/mall-common/src/main/java/com/suisung/mall/common/constant/MqConstant.java index f0ff94fb..08b49df9 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/constant/MqConstant.java +++ b/mall-common/src/main/java/com/suisung/mall/common/constant/MqConstant.java @@ -14,6 +14,7 @@ public class MqConstant { public static final Integer FAILURE = 2; // 消息消费失败更改状态 public static final Integer DELIVERED = 3; // 消息重试消费成功更改状态 public static final Integer MAX_COUNT = 3; // 消息重新投递最大重试次数 + public static final String SHOP_EXCHANGE = "shop-event-exchange"; // SHOP服务交换机 public static final String ACCOUNT_EXCHANGE = "account-event-exchange"; // ACCOUNT服务交换机 public static final String PAY_EXCHANGE = "pay-event-exchange"; // PAY服务交换机 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/MqMessageServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/MqMessageServiceImpl.java index 2bf95821..f82caac7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/MqMessageServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/MqMessageServiceImpl.java @@ -54,27 +54,9 @@ public class MqMessageServiceImpl extends BaseServiceImpl orderIds) { + public void processOrderJumpPathAsync(List orderIds) { if (CollectionUtils.isEmpty(orderIds)) { return; } @@ -5195,15 +5195,15 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq("store_id", storeId != null ? storeId : 0) .eq("category", category) + .eq("status", CommonConstant.Enable) .orderByAsc("template_id"); ShopStorePrinterTemplate shopStorePrinterTemplate = findOne(queryWrapper); @@ -46,6 +48,7 @@ public class ShopStorePrinterTemplateServiceImpl extends BaseServiceImpl #${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
-配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(之后20-30分钟)
+配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
From d530054e031476820535eb782dfd9cc84ca24f67 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sat, 29 Nov 2025 17:18:47 +0800 Subject: [PATCH 58/81] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E5=92=8C=E6=B7=BB=E5=8A=A0=E6=89=93=E5=8D=B0=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/mobile/LakalaController.java | 2 +- .../impl/ShopOrderBaseServiceImpl.java | 2 +- .../impl/ShopOrderReturnServiceImpl.java | 16 +++++++++-- .../service/ShopStorePrinterService.java | 3 +-- .../impl/ShopStorePrinterServiceImpl.java | 27 ++++++++++--------- .../mapper/order/ShopOrderReturnMapper.xml | 2 +- .../templates/refund_order_printer.txt | 4 +-- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 43ee78a6..547dcf72 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -94,7 +94,7 @@ public class LakalaController extends BaseControllerImpl { // return lakalaApiService.tradeQuery(paramsJSON.getInt("storeId"), paramsJSON.getStr("orderId")); - return shopStorePrinterService.printShopStoreReturnOrder(paramsJSON.getStr("orderId"), paramsJSON.getStr("returnId")); + return shopStorePrinterService.printShopStoreReturnOrder(paramsJSON.getStr("returnId")); } @ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 2cfd74d1..6ba8d32b 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -5195,7 +5195,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl Convert.toInt(getCurrentUser().getStore_id())); - List return_ids = Convert.toList(String.class, shopOrderReturn.getReturn_id()); + String returnId = shopOrderReturn.getReturn_id(); + + List return_ids = Convert.toList(String.class, returnId); List orderReturns = gets(return_ids); if (!CheckUtil.checkDataRights(store_id, orderReturns, ShopOrderReturn::getStore_id)) { @@ -1416,6 +1426,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl itemQueryWrapper = new QueryWrapper<>(); itemQueryWrapper.eq("order_id", orderId); List allOrderItems = shopOrderItemService.find(itemQueryWrapper); - if (CollectionUtil.isEmpty(allOrderItems)) { logger.warn("订单剩余商品退款申请失败:订单商品表为空,订单ID: {}", orderId); throw new ApiException(I18nUtil._("订单商品表为空!")); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java index 7aa53d9f..638e06a4 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java @@ -83,11 +83,10 @@ public interface ShopStorePrinterService extends IBaseService /** * 退货成功后,立即打印门店的退货信息 * - * @param orderId * @param returnId * @return */ - Boolean printShopStoreReturnOrder(String orderId, String returnId); + Boolean printShopStoreReturnOrder(String returnId); /** * 获取店铺所有有效打印机 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java index 31f14fb4..23b062bd 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java @@ -32,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.util.Pair; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -407,7 +408,7 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl * 该方法通过调用飞鹅打票机接口,完成指定订单的退货小票打印功能。主要流程包括: * 1. 校验订单号是否合法; @@ -417,12 +418,12 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl * - * @param orderId 订单编号,不能为空 * @param returnId 退货单编号,用于标识具体的退货记录 * @return 打印操作是否成功,成功返回 true,否则返回 false */ + @Async @Override - public Boolean printShopStoreReturnOrder(String orderId, String returnId) { + public Boolean printShopStoreReturnOrder(String returnId) { logger.debug("#### 调用飞鹅打票机的打印退款订单操作开始 ####"); // 参数校验 @@ -433,16 +434,16 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl orderItems = binding.getOrder_items(); + List orderItems = orderPrintVO.getOrder_items(); if (CollUtil.isEmpty(orderItems)) { logger.error("订单{}商品信息为空,无法打印小票。", orderId); return false; @@ -479,10 +480,10 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl用户退款订单
+用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
@@ -78,4 +78,4 @@ ${store_name}
--------------------------------
#${order_pickup_num_str}
买家备注:${order_message!'-'}
配送时间:${delivery_time}
--------------------------------
订单编号:${order_id}
订单来源:微信小程序
支付方式:微信支付
配送来源:顺丰同城
付款时间:${payment_time}
--------------------------------
商品名称 数量 金额
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
商品总件数:${order_items_count!0}
商品总额:¥${order_product_amount?string('0.00')}
押金:¥${(yajin!0)?string('0.00')}
运费:¥${order_shipping_fee?string('0.00')}
会员权益:-¥${(quanyi!0)?string('0.00')}
秒杀:-¥${(miaosha!0)?string('0.00')}
实付金额:¥${order_payment_amount?string('0.00')}
<#if seller_message?default("")?trim?length gt 1>--------------------------------
商家备注:${seller_message!'---'}
--------------------------------
收货人:${buyer_user_name!''}
收货人手机:${store_tel!''}
收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}
--------------------------------
门店:${store_name}
门店电话:${store_tel!'-'}
收银员:${cashier!'-'}
带参模版: -用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
申请退款:${return_add_time?string('yyyy-MM-dd HH:mm:ss')}
确认退款:${return_finish_time?string('yyyy-MM-dd HH:mm:ss')}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}
+用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
申请退款:${return_add_time?string('yyyy-MM-dd HH:mm:ss')}
确认退款:${return_finish_time?string('yyyy-MM-dd HH:mm:ss')}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
<#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}
From e59fa567843e682f4c270ce2e3a64e4d9c1aae6d Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Sat, 29 Nov 2025 17:30:27 +0800 Subject: [PATCH 59/81] =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E8=A3=85=E4=BF=AE?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E5=95=86=E5=93=81=E6=98=BE=E7=A4=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/shop/page/service/impl/ShopPageBaseServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java index 3b99f6ff..7d697301 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java @@ -445,17 +445,18 @@ public class ShopPageBaseServiceImpl extends BaseServiceImpl product_item_opl = product_item_rows.stream().filter(s -> ObjectUtil.equal(Convert.toLong(s.get("item_id")), did)).findFirst(); if (product_item_opl.isPresent()) { Map product_item_row = product_item_opl.get(); // 获取商品实时数据 String path = ""; - String product_name = ""; + Map product_basic_info_row = shopProductBaseService.getProductBasicInfo(Convert.toLong(product_item_row.get("product_id")), Convert.toInt(product_item_row.get("store_id"))); if (product_basic_info_row != null) { path = product_basic_info_row.get("product_image").toString(); - product_name = product_basic_info_row.get("product_name").toString(); + // product_name = product_basic_info_row.get("product_name").toString(); } //BigDecimal itemSalePrice = Convert.toBigDecimal(((JSONObject) item).get("ItemSalePrice")); From dcaf638b5886cdbffa66068a6df510f0c3186d69 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Mon, 1 Dec 2025 14:47:00 +0800 Subject: [PATCH 60/81] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=A9=BA=E5=86=85=E5=AE=B9=E6=97=A0=E9=BB=98=E8=AE=A4=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/product/service/impl/ShopProductBaseServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java index 4c307b9d..8676d492 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java @@ -492,6 +492,9 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl item_image_other = Convert.toList(String.class, productItemMap.get("color_img")); String _str_item_spec = (String) productItemMap.get("product_spec"); JSONArray _item_spec = StrUtil.isNotBlank(_str_item_spec) ? JSONObject.parseArray(_str_item_spec) : null; From 2eed30bdf447aca24369e31d23711fcf8b3678e9 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Mon, 1 Dec 2025 16:08:36 +0800 Subject: [PATCH 61/81] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=A9=BA=E5=86=85=E5=AE=B9=E9=BB=98=E8=AE=A4=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/product/ShopProductImage.java | 2 +- .../admin/ShopProductInfoController.java | 11 +++++++++ .../impl/ShopProductBaseServiceImpl.java | 23 ++++++++++++++++--- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/product/ShopProductImage.java b/mall-common/src/main/java/com/suisung/mall/common/modules/product/ShopProductImage.java index c90d34dc..1d3aa8b7 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/product/ShopProductImage.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/product/ShopProductImage.java @@ -42,7 +42,7 @@ public class ShopProductImage implements Serializable { @ApiModelProperty(value = "规格值") private String color_name; - @ApiModelProperty(value = "商品主图") + @ApiModelProperty(value = "商品主图,0是编辑空图片,1是同步空图片") @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) private String item_image_default; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/controller/admin/ShopProductInfoController.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/controller/admin/ShopProductInfoController.java index 49bf85b3..b1296198 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/product/controller/admin/ShopProductInfoController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/controller/admin/ShopProductInfoController.java @@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; /** *

@@ -114,6 +115,16 @@ public class ShopProductInfoController { QueryWrapper imageQueryWrapper = new QueryWrapper<>(); imageQueryWrapper.eq("product_id", product_id); List shopProductImages = imageService.find(imageQueryWrapper); + if(!shopProductImages.isEmpty()) { + shopProductImages=shopProductImages.stream().peek(s->{ + if(s.getItem_image_default().equals("0")||s.getItem_image_default().equals("1")) { + s.setItem_image_default(""); + } + if(s.getItem_image_other().equals("0")||s.getItem_image_other().equals("1")) { + s.setItem_image_other(""); + } + }).collect(Collectors.toList()); + } // shop_product_assist_index QueryWrapper indexQueryWrapper = new QueryWrapper<>(); indexQueryWrapper.eq("product_id", product_id); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java index 8676d492..082107a7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java @@ -493,7 +493,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl item_image_other = Convert.toList(String.class, productItemMap.get("color_img")); String _str_item_spec = (String) productItemMap.get("product_spec"); @@ -587,7 +587,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl shopProductBases = gets(product_ids); + if(!shopProductBases.isEmpty()){ + shopProductBases=shopProductBases.stream().peek(s->{ + if (s.getProduct_image().equals("0")||s.getProduct_image().equals("1")){ + s.setProduct_image(""); + } + }).collect(Collectors.toList()); + } product_base_rows = Convert.toList(Map.class, shopProductBases); List ShopProductInfos = shopProductInfoService.gets(product_ids); List product_info_rows = Convert.toList(Map.class, ShopProductInfos); @@ -6507,7 +6514,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl cond_row = new QueryWrapper<>(); if (StrUtil.isNotBlank(productNumber)) { - cond_row.eq("product_number", productNumber); + cond_row.eq("product_number", productNumber.trim()); } cond_row.eq("store_id", store_id); List lists = shopProductIndexService.list(cond_row); @@ -6562,6 +6569,16 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl imageQueryWrapper = new QueryWrapper<>(); imageQueryWrapper.eq("product_id", productId); List shopProductImages = shopProductImageService.find(imageQueryWrapper); + if(!shopProductImages.isEmpty()){ + shopProductImages=shopProductImages.stream().peek(s->{ + if(s.getItem_image_default().equals("0")||s.getItem_image_default().equals("1")){ + s.setItem_image_default(""); + } + if(s.getItem_image_other().equals("0")||s.getItem_image_other().equals("1")){ + s.setItem_image_other(""); + } + }).collect(Collectors.toList()); + } // shop_product_assist_index QueryWrapper indexQueryWrapper = new QueryWrapper<>(); indexQueryWrapper.eq("product_id", productId); From 2ea022091ca0d166e03abc28da297cd994749587 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Mon, 1 Dec 2025 17:35:52 +0800 Subject: [PATCH 62/81] =?UTF-8?q?=E5=8F=96=E6=B6=88=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E4=B9=9F=E8=A6=81=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E9=A1=BA=E4=B8=B0=E5=90=8C=E5=9F=8E=E7=9A=84=E9=85=8D=E9=80=81?= =?UTF-8?q?=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/EsignController.java | 4 +- .../EsignContractFillingFileService.java | 5 +- .../esign/service/EsignContractService.java | 28 +- .../EsignContractFillingFileServiceImpl.java | 599 ++++++++++-------- .../impl/EsignContractServiceImpl.java | 303 ++++++--- .../impl/EsignPlatformInfoServiceImpl.java | 7 +- .../impl/ShopOrderBaseServiceImpl.java | 12 + .../impl/ShopOrderReturnServiceImpl.java | 22 +- .../service/impl/SFExpressApiServiceImpl.java | 181 +++--- .../mobile/ShopMchEntryController.java | 2 +- .../store/service/ShopMchEntryService.java | 8 + .../service/impl/ShopMchEntryServiceImpl.java | 31 + .../impl/ShopStoreBaseServiceImpl.java | 40 ++ 13 files changed, 745 insertions(+), 497 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/controller/admin/EsignController.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/controller/admin/EsignController.java index 620147fd..93d1d7e9 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/controller/admin/EsignController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/controller/admin/EsignController.java @@ -50,7 +50,7 @@ public class EsignController extends BaseControllerImpl { @ApiOperation(value = "管理员发起签署电子合同流程", notes = "基于文件发起签署电子合同") @RequestMapping(value = "/sign-flow/create-by-file", method = RequestMethod.POST) public CommonResult signFlowCreateByFile(@RequestBody JSONObject paramsJSON) { - return esignContractService.signFlowCreateByFile(paramsJSON.getStr("mchMobile")); + return esignContractService.signFlowCreateByFile(paramsJSON.getInt("store_id")); } @ApiOperation(value = "签署电子合同流程通知接收", notes = "签署电子合同流程通知接收") @@ -62,6 +62,6 @@ public class EsignController extends BaseControllerImpl { @ApiOperation(value = "查看已签署的电子合同文件", notes = "管理员查看已签署的电子合同文件") @RequestMapping(value = "/signed/contract/file", method = RequestMethod.POST) public CommonResult getSignedContactFile(@RequestBody JSONObject paramsJSON) { - return esignContractService.getSignedContactFile(paramsJSON.getStr("mchMobile")); + return esignContractService.getSignedContactFile(paramsJSON.getInt("store_id")); } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractFillingFileService.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractFillingFileService.java index fafe710d..11fbcd4a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractFillingFileService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractFillingFileService.java @@ -18,11 +18,10 @@ public interface EsignContractFillingFileService { /** * 填充合同模版,生成合同文件地址 * - * @param mchMobile 入驻商家注册手机号 - * @param platLicenseNumber 平台方(代理商方)营业执照号 + * @param storeId 入驻成功商家的店铺Id * @return */ - Boolean fillDocTemplate(String mchMobile, String platLicenseNumber); + Boolean fillDocTemplate(Integer storeId); /** * 获取模版的甲方与乙方印章XY位置数据 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractService.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractService.java index 41b7afe1..afa26800 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignContractService.java @@ -21,18 +21,18 @@ public interface EsignContractService { /** * 根据商家注册手机号,发起合同签署流程 * - * @param mchMobile + * @param storeId * @return */ - CommonResult signFlowCreateByFile(String mchMobile); + CommonResult signFlowCreateByFile(Integer storeId); /** * 内部调用:发起合同签署流程 * - * @param mchMobile + * @param storeId * @return */ - Pair innerSignFlowCreateByFile(String mchMobile); + Pair innerSignFlowCreateByFile(Integer storeId); /** * 签署流程结束异步通知(由e签宝通知) @@ -44,10 +44,10 @@ public interface EsignContractService { /** * 管理员查看已签署的电子合同文件 * - * @param mchMobile + * @param storeId * @return */ - CommonResult getSignedContactFile(String mchMobile); + CommonResult getSignedContactFile(Integer storeId); /** * 更新合同流程ID和文件地址和状态 @@ -131,4 +131,20 @@ public interface EsignContractService { * @return */ Boolean updateContractStoreId(String mchMobile, Integer storeId); + + /** + * 根据店铺Id,获取一条合同信息 + * + * @param storeId + * @return + */ + EsignContract getEsignContractByStoreId(Integer storeId); + + /** + * 根据店铺Id,获取合同状态和下载地址 + * + * @param storeId + * @return + */ + EsignContract getEsignContractStatusUrl(Integer storeId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java index 88ba9d90..de141c64 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java @@ -9,6 +9,7 @@ package com.suisung.mall.shop.esign.service.impl; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -21,6 +22,8 @@ import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.modules.esign.EsignContractFillingFile; import com.suisung.mall.common.modules.esign.EsignPlatformInfo; import com.suisung.mall.common.modules.store.ShopMchEntry; +import com.suisung.mall.common.modules.store.ShopStoreBase; +import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.common.utils.StringUtils; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.esign.mapper.EsignContractFillingFileMapper; @@ -33,6 +36,7 @@ import com.suisung.mall.shop.esign.utils.enums.EsignRequestType; import com.suisung.mall.shop.esign.utils.exception.EsignDemoException; import com.suisung.mall.shop.page.service.OssService; import com.suisung.mall.shop.store.service.ShopMchEntryService; +import com.suisung.mall.shop.store.service.ShopStoreBaseService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; @@ -41,6 +45,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -79,6 +84,10 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl - * 后台管理员审核商家通过之后,触发调用这个方法,生成未签署合同文件,预备签署 + * 拉卡拉审核通过之后,触发调用这个方法,生成未签署合同文件,预备签署 * - * @param mchMobile 入驻商家(甲方)的注册手机号 - * @param platLicenseNumber 平台方(代理商方)(乙方)营业执照号 - * @return + * @param storeId 入驻成功商家的店铺Id + * @return Boolean 是否成功生成合同文件 */ @Override - public Boolean fillDocTemplate(String mchMobile, String platLicenseNumber) { - if (StrUtil.isEmpty(mchMobile)) { - log.error("商家手机号为空"); + public Boolean fillDocTemplate(Integer storeId) { + // 1. 参数校验 + if (CheckUtil.isEmpty(storeId)) { + log.error("商家店铺Id为空"); return false; } - // 获取平台方的信息 - EsignPlatformInfo esignPlatformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, platLicenseNumber); + // 2. 获取平台方信息 + EsignPlatformInfo esignPlatformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, ""); if (ObjectUtils.isEmpty(esignPlatformInfo)) { log.error("请添加平台方(代理商方)信息"); - return null; + return false; } - // 获取入驻商家(审批通过的)的信息 - ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByCondition(mchMobile, "", CommonConstant.MCH_APPR_STA_PASS); + // 3. 获取入驻商家(审批通过的)的信息 + ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId); if (shopMchEntry == null) { - log.error("缺少商家入驻信息"); - return null; + log.error("缺少商家入驻信息, storeId: {}", storeId); + return false; } - // 代理商信息 + // 4. 检查商家审批状态 + if (!CommonConstant.MCH_APPR_STA_PASS.equals(shopMchEntry.getApproval_status())) { + log.error("入驻商家审批未通过,当前状态: {}, storeId: {}", shopMchEntry.getApproval_status(), storeId); + return false; + } + + ShopStoreBase shopStoreBase = shopStoreBaseService.getShopStoreBaseByStoreId(storeId); + if (ObjectUtils.isEmpty(shopStoreBase)) { + log.error("缺少商家店铺信息, storeId: {}", storeId); + return false; + } + + BigDecimal splitRatio = shopStoreBase.getSplit_ratio(); + if (CheckUtil.isEmpty(splitRatio)) { + log.error("缺少商家店铺分账比例,从入驻申请数据获取分账比例, storeId: {}", storeId); + splitRatio = shopMchEntry.getSplit_ratio(); + } + + // 5. 获取代理商信息 EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMchEntry.getDistributor_id()); - String apiaddr = "/v3/files/create-by-doc-template"; + String apiAddr = "/v3/files/create-by-doc-template"; EsignRequestType requestType = EsignRequestType.POST; - // 获取平台方(代理商方)合同模版信息 + // 6. 获取平台方合同模版信息 JSONArray templates = JSONUtil.parseArray(esignPlatformInfo.getDoc_template()); - if (ObjectUtils.isEmpty(templates) || templates.size() <= 0) { + if (templates == null || templates.isEmpty()) { log.error("缺少平台方(代理商方)合同模版信息"); - return null; + return false; } + // 7. 准备基础数据 String today = DateUtil.format(new Date(), "yyyy年MM月dd日"); // 甲方公司名称,甲方是个人的时候,没有公司名,直接用店铺名(个人实名) - String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getBiz_license_company() : shopMchEntry.getStore_name() + "(" + shopMchEntry.getContact_name() + ")"; + String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) + ? shopMchEntry.getBiz_license_company() + : shopMchEntry.getStore_name() + "(" + shopMchEntry.getContact_name() + ")"; String platCompany = esignPlatformInfo.getLicense_company(); // 甲方法人姓名,甲方是个人的时候,没有法人,直接用个人实名 - String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getLegal_person_name() : shopMchEntry.getContact_name(); - String LegalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getLegal_person_mobile() : shopMchEntry.getLogin_mobile(); + String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) + ? shopMchEntry.getLegal_person_name() + : shopMchEntry.getContact_name(); + String legalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) + ? shopMchEntry.getLegal_person_mobile() + : shopMchEntry.getLogin_mobile(); // 甲方法人身份证号,甲方是个人的时候,没有法人,直接用个人身份证 - String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getLegal_person_id_number() : shopMchEntry.getIndividual_id_number(); - + String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) + ? shopMchEntry.getLegal_person_id_number() + : shopMchEntry.getIndividual_id_number(); String contractNumber = StringUtils.genLklOrderNo(4); - int successCnt = 0; - // 模版文件里有三份合同,顺序排列的: 1.平台商户入驻服务框架协议 2.小发同城服务费结算 3.结算授权委托书 + log.info("开始为商家生成合同文件, storeId: {}, mobile: {}", storeId, shopMchEntry.getLogin_mobile()); + + // 8. 遍历模版文件生成合同(模版文件里有三份合同,顺序排列的: 1.平台商户入驻服务框架协议 2.小发同城服务费结算 3.结算授权委托书) for (JSONObject template : templates.jsonIter()) { - // 从商家信息里获取模版的信息 - String templateId = template.getStr("template_id"); - String fileName = template.getStr("template_name"); - int seq = template.getInt("seq"); + try { + // 从商家信息里获取模版的信息 + String templateId = template.getStr("template_id"); + String fileName = template.getStr("template_name"); + int seq = template.getInt("seq"); - // 获取填充模版的数据 - JSONObject fillJson = new JSONObject(); - fillJson.put("docTemplateId", templateId) - .put("fileName", fileName); + log.debug("处理合同模版: templateId={}, fileName={}, seq={}", templateId, fileName, seq); + // 9. 构建填充模版的数据 + JSONObject fillJson = new JSONObject(); + fillJson.put("docTemplateId", templateId) + .put("fileName", fileName); - JSONArray list = new JSONArray(); - EsignPlatformInfo finalEsignPlatformInfo = esignPlatformInfo; + JSONArray list = new JSONArray(); - list.add(new HashMap() {{ - put("componentKey", "plat_contracts"); - put("componentValue", "《平台商户入驻服务框架协议》和《小发同城服务费结算》"); - }}); - - // 签署时间 - for (int i = 1; i <= 3; i++) { - int finalI = i; + // 10. 填充合同组件数据 + // 平台合同名称 list.add(new HashMap() {{ - put("componentKey", "mch_sign_date" + finalI); - put("componentValue", today); + put("componentKey", "plat_contracts"); + put("componentValue", "《平台商户入驻服务框架协议》和《小发同城服务费结算》"); }}); - } - for (int i = 1; i <= 3; i++) { - int finalI = i; - list.add(new HashMap() {{ - put("componentKey", "plat_sign_date" + finalI); - put("componentValue", today); - }}); - } - - if (CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())) { - // 甲方公司名称,甲方是个人的时候,没有公司名,直接用店铺名 - for (int i = 1; i <= 17; i++) { + // 签署时间(甲方) + for (int i = 1; i <= 3; i++) { int finalI = i; list.add(new HashMap() {{ - put("componentKey", "mch_company" + finalI); - put("componentValue", mchCompany); + put("componentKey", "mch_sign_date" + finalI); + put("componentValue", today); }}); } - } else { - // 甲方公司名称,甲方是个人的时候,没有公司名,直接用店铺名 - for (int i = 1; i <= 16; i++) { + + // 签署时间(乙方) + for (int i = 1; i <= 3; i++) { + int finalI = i; + list.add(new HashMap() {{ + put("componentKey", "plat_sign_date" + finalI); + put("componentValue", today); + }}); + } + + // 甲方公司名称 + int mchCompanyCount = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? 17 : 16; + for (int i = 1; i <= mchCompanyCount; i++) { int finalI = i; list.add(new HashMap() {{ put("componentKey", "mch_company" + finalI); @@ -199,233 +230,239 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl() {{ put("componentKey", "mch_company17"); put("componentValue", shopMchEntry.getContact_name()); }}); } - } - // 甲方法人姓名,甲方是个人的时候,没有法人,直接用个人实名 - for (int i = 1; i <= 4; i++) { - int finalI = i; - list.add(new HashMap() {{ - put("componentKey", "mch_legal_person_name" + finalI); - put("componentValue", legalPersonName); - }}); - } - - // 甲方法人手机号 - for (int i = 1; i <= 3; i++) { - int finalI = i; - list.add(new HashMap() {{ - put("componentKey", "mch_legal_person_mobile" + finalI); - put("componentValue", LegalPersonMobile); - }}); - } - - // 甲方身份证号码 - list.add(new HashMap() {{ - put("componentKey", "mch_legal_person_id_number1"); - put("componentValue", legalPersonIdNumber); - }}); - - list.add(new HashMap() {{ - put("componentKey", "mch_store_name1"); - put("componentValue", shopMchEntry.getStore_name()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "rule_no"); - put("componentValue", 3); - }}); - - list.add(new HashMap() {{ - put("componentKey", "mch_ratio"); - put("componentValue", shopMchEntry.getSplit_ratio()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "settlement_method"); - put("componentValue", shopMchEntry.getSettlement_method()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "mch_address1"); - put("componentValue", shopMchEntry.getStore_address()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "mch_bank1"); - put("componentValue", shopMchEntry.getBank_name()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "mch_account_number1"); - put("componentValue", shopMchEntry.getAccount_number()); - }}); - - // 乙方公司名称 - list.add(new HashMap() {{ - put("componentKey", "plat_company1"); - put("componentValue", platCompany + "和代理商"); - }}); - - for (int i = 2; i <= 5; i++) { - int finalI = i; - list.add(new HashMap() {{ - put("componentKey", "plat_company" + finalI); - put("componentValue", platCompany); - }}); - } - - for (int i = 1; i <= 2; i++) { - int finalI = i; - list.add(new HashMap() {{ - put("componentKey", "plat_mobile" + finalI); - put("componentValue", finalEsignPlatformInfo.getLegal_person_mobile()); - }}); - } - - list.add(new HashMap() {{ - put("componentKey", "plat_email1"); - put("componentValue", finalEsignPlatformInfo.getEmail()); - }}); - - - list.add(new HashMap() {{ - put("componentKey", "plat_email1"); - put("componentValue", finalEsignPlatformInfo.getEmail()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "plat_email1"); - put("componentValue", finalEsignPlatformInfo.getEmail()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "plat_email1"); - put("componentValue", finalEsignPlatformInfo.getEmail()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "plat_email1"); - put("componentValue", finalEsignPlatformInfo.getEmail()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "plat_email1"); - put("componentValue", finalEsignPlatformInfo.getEmail()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "plat_bank1"); - put("componentValue", finalEsignPlatformInfo.getRec_acc_bank_name()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "plat_account_number1"); - put("componentValue", finalEsignPlatformInfo.getRec_acc_card_no()); - }}); - - // 代理商相关 - if (distributor != null) { - // 有代理商的时候,才填充代理商的信息 - list.add(new HashMap() {{ - put("componentKey", "distr_company1"); - put("componentValue", distributor.getLicense_company()); - }}); - list.add(new HashMap() {{ - put("componentKey", "distr_mobile1"); - put("componentValue", distributor.getLegal_person_mobile()); - }}); - list.add(new HashMap() {{ - put("componentKey", "distr_company2"); - put("componentValue", distributor.getLicense_company()); - }}); - list.add(new HashMap() {{ - put("componentKey", "distr_bank1"); - put("componentValue", distributor.getRec_acc_bank_name()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "distr_account_number1"); - put("componentValue", distributor.getRec_acc_card_no()); - }}); - - list.add(new HashMap() {{ - put("componentKey", "distr_sign_date1"); - put("componentValue", today); - }}); - } else { - // 有代理商的时候,才填充代理商的信息 - list.add(new HashMap() {{ - put("componentKey", "distr_company1"); - put("componentValue", "无"); - }}); - list.add(new HashMap() {{ - put("componentKey", "distr_mobile1"); - put("componentValue", "无"); - }}); - list.add(new HashMap() {{ - put("componentKey", "distr_company2"); - put("componentValue", "无"); - }}); - list.add(new HashMap() {{ - put("componentKey", "distr_bank1"); - put("componentValue", "无"); - }}); - - list.add(new HashMap() {{ - put("componentKey", "distr_account_number1"); - put("componentValue", "无"); - }}); - - } - - fillJson.put("components", list); - - String jsonParma = fillJson.toString(); - - //生成签名鉴权方式的的header - Map header = null; - try { - header = EsignHttpHelper.signAndBuildSignAndJsonHeader(appId, appSecret, jsonParma, requestType.name(), apiaddr, debug); - //发起接口请求 - EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(serverUrl, apiaddr, requestType, jsonParma, header, debug); - log.info("合同生成数据:{}", createByDocTemplate); - if (createByDocTemplate.getStatus() != 200) { - return false; + // 甲方法人姓名 + for (int i = 1; i <= 4; i++) { + int finalI = i; + list.add(new HashMap() {{ + put("componentKey", "mch_legal_person_name" + finalI); + put("componentValue", legalPersonName); + }}); } - EsignContractFillingFile esignContractFillingFile = new EsignContractFillingFile(); + // 甲方法人手机号 + for (int i = 1; i <= 3; i++) { + int finalI = i; + list.add(new HashMap() {{ + put("componentKey", "mch_legal_person_mobile" + finalI); + put("componentValue", legalPersonMobile); + }}); + } + // 甲方身份证号码 + list.add(new HashMap() {{ + put("componentKey", "mch_legal_person_id_number1"); + put("componentValue", legalPersonIdNumber); + }}); + + // 甲方店铺名称 + list.add(new HashMap() {{ + put("componentKey", "mch_store_name1"); + put("componentValue", shopMchEntry.getStore_name()); + }}); + + // 规则编号 + list.add(new HashMap() {{ + put("componentKey", "rule_no"); + put("componentValue", 3); + }}); + + // 分账比例 + BigDecimal finalSplitRatio = splitRatio; + list.add(new HashMap() {{ + put("componentKey", "mch_ratio"); + put("componentValue", finalSplitRatio); + }}); + + // 结算方式 + list.add(new HashMap() {{ + put("componentKey", "settlement_method"); + put("componentValue", shopMchEntry.getSettlement_method()); + }}); + + // 甲方地址 + list.add(new HashMap() {{ + put("componentKey", "mch_address1"); + put("componentValue", shopMchEntry.getStore_address()); + }}); + + // 甲方银行 + list.add(new HashMap() {{ + put("componentKey", "mch_bank1"); + put("componentValue", shopMchEntry.getBank_name()); + }}); + + // 甲方账户号 + list.add(new HashMap() {{ + put("componentKey", "mch_account_number1"); + put("componentValue", shopMchEntry.getAccount_number()); + }}); + + // 乙方公司名称 + list.add(new HashMap() {{ + put("componentKey", "plat_company1"); + put("componentValue", platCompany + "和代理商"); + }}); + + // 其他乙方公司名称 + for (int i = 2; i <= 5; i++) { + int finalI = i; + list.add(new HashMap() {{ + put("componentKey", "plat_company" + finalI); + put("componentValue", platCompany); + }}); + } + + // 乙方手机号 + for (int i = 1; i <= 2; i++) { + int finalI = i; + list.add(new HashMap() {{ + put("componentKey", "plat_mobile" + finalI); + put("componentValue", esignPlatformInfo.getLegal_person_mobile()); + }}); + } + + // 乙方邮箱(重复填充,但保持原逻辑) + for (int i = 0; i < 6; i++) { + list.add(new HashMap() {{ + put("componentKey", "plat_email1"); + put("componentValue", esignPlatformInfo.getEmail()); + }}); + } + + // 乙方银行 + list.add(new HashMap() {{ + put("componentKey", "plat_bank1"); + put("componentValue", esignPlatformInfo.getRec_acc_bank_name()); + }}); + + // 乙方账户号 + list.add(new HashMap() {{ + put("componentKey", "plat_account_number1"); + put("componentValue", esignPlatformInfo.getRec_acc_card_no()); + }}); + + // 11. 处理代理商相关数据 + if (distributor != null) { + // 有代理商的时候,填充代理商的信息 + list.add(new HashMap() {{ + put("componentKey", "distr_company1"); + put("componentValue", distributor.getLicense_company()); + }}); + list.add(new HashMap() {{ + put("componentKey", "distr_mobile1"); + put("componentValue", distributor.getLegal_person_mobile()); + }}); + list.add(new HashMap() {{ + put("componentKey", "distr_company2"); + put("componentValue", distributor.getLicense_company()); + }}); + list.add(new HashMap() {{ + put("componentKey", "distr_bank1"); + put("componentValue", distributor.getRec_acc_bank_name()); + }}); + + list.add(new HashMap() {{ + put("componentKey", "distr_account_number1"); + put("componentValue", distributor.getRec_acc_card_no()); + }}); + + list.add(new HashMap() {{ + put("componentKey", "distr_sign_date1"); + put("componentValue", today); + }}); + + log.debug("已填充代理商信息: {}", distributor.getLicense_company()); + } else { + // 无代理商时填充默认值 + list.add(new HashMap() {{ + put("componentKey", "distr_company1"); + put("componentValue", "无"); + }}); + list.add(new HashMap() {{ + put("componentKey", "distr_mobile1"); + put("componentValue", "无"); + }}); + list.add(new HashMap() {{ + put("componentKey", "distr_company2"); + put("componentValue", "无"); + }}); + list.add(new HashMap() {{ + put("componentKey", "distr_bank1"); + put("componentValue", "无"); + }}); + + list.add(new HashMap() {{ + put("componentKey", "distr_account_number1"); + put("componentValue", "无"); + }}); + + log.debug("未配置代理商信息,使用默认值"); + } + + fillJson.put("components", list); + String jsonParam = fillJson.toString(); + + // 12. 调用e签宝API生成合同文件 + Map header = EsignHttpHelper.signAndBuildSignAndJsonHeader( + appId, appSecret, jsonParam, requestType.name(), apiAddr, debug); + + // 发起接口请求 + EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp( + serverUrl, apiAddr, requestType, jsonParam, header, debug); + + log.info("合同生成API调用结果: status={}, body={}", + createByDocTemplate.getStatus(), createByDocTemplate.getBody()); + + if (createByDocTemplate.getStatus() != 200) { + log.error("调用e签宝生成合同文件接口失败, status: {}", createByDocTemplate.getStatus()); + continue; // 继续处理下一个模版 + } + + // 13. 解析API返回结果 JSONObject jsonObject = JSONUtil.parseObj(createByDocTemplate.getBody()).getJSONObject("data"); - esignContractFillingFile.setUnsigned_contract_url(jsonObject.getStr("fileDownloadUrl")); + String fileDownloadUrl = jsonObject.getStr("fileDownloadUrl"); String fileId = jsonObject.getStr("fileId"); - // 把合同文件 url 上传到cos服务器 -// String contractPath = StrUtil.isBlank(shopMchEntry.getBiz_license_number()) ? mchMobile : shopMchEntry.getBiz_license_number(); - String cosFileName = TENGXUN_DEFAULT_DIR.concat("/").concat("contract") - .concat("/").concat(shopMchEntry.getLogin_mobile()).concat("/") - .concat(jsonObject.getStr("fileId")).concat(".pdf"); - // 上传到cos服务器 - String localFileUrl = ossService.uploadObject4OSS(esignContractFillingFile.getUnsigned_contract_url(), cosFileName); - esignContractFillingFile.setUnsigned_contract_local_url(localFileUrl); + if (StrUtil.isBlank(fileDownloadUrl) || StrUtil.isBlank(fileId)) { + log.error("e签宝返回的合同文件信息不完整, fileDownloadUrl: {}, fileId: {}", fileDownloadUrl, fileId); + continue; + } + + // 14. 创建合同填充文件记录 + EsignContractFillingFile esignContractFillingFile = new EsignContractFillingFile(); + esignContractFillingFile.setUnsigned_contract_url(fileDownloadUrl); esignContractFillingFile.setFile_id(fileId); + // 15. 上传合同文件到OSS + String cosFileName = TENGXUN_DEFAULT_DIR.concat("/contract/") + .concat(shopMchEntry.getLogin_mobile()).concat("/") + .concat(fileId).concat(".pdf"); + + String localFileUrl = ossService.uploadObject4OSS(fileDownloadUrl, cosFileName); + if (StrUtil.isBlank(localFileUrl)) { + log.error("上传合同文件到OSS失败, fileId: {}", fileId); + continue; + } + + esignContractFillingFile.setUnsigned_contract_local_url(localFileUrl); esignContractFillingFile.setDoc_template_id(templateId); esignContractFillingFile.setContract_number(contractNumber + seq); esignContractFillingFile.setContract_name("商户入驻小发同城平台合同协议"); - esignContractFillingFile.setStore_id(contractNumber); - esignContractFillingFile.setMobile(mchMobile); - esignContractFillingFile.setDoc_template_filling_values(jsonParma); + esignContractFillingFile.setStore_id(Convert.toStr(storeId)); + esignContractFillingFile.setMobile(shopMchEntry.getLogin_mobile()); + esignContractFillingFile.setDoc_template_filling_values(jsonParam); esignContractFillingFile.setSeq(seq); esignContractFillingFile.setStatus(CommonConstant.Enable); - // 获取印章的位置信息,写入数据库 + // 16. 获取印章位置信息 Map signPositionMap = getSignPosition(templateId, fileId); if (signPositionMap != null) { if (signPositionMap.get("mch") != null) { @@ -441,22 +478,34 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl 0; + boolean result = successCnt > 0; + log.info("合同文件生成完成, storeId: {}, 总模版数: {}, 成功处理数: {}, 结果: {}", + storeId, templates.size(), successCnt, result); + + return result; } + /** * 获取模版的甲方与乙方印章XY位置数据 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java index 32e9a451..fbfa2ae5 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java @@ -14,6 +14,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.suisung.mall.common.api.CommonResult; @@ -22,6 +23,7 @@ import com.suisung.mall.common.modules.esign.EsignContract; import com.suisung.mall.common.modules.esign.EsignContractFillingFile; import com.suisung.mall.common.modules.esign.EsignPlatformInfo; import com.suisung.mall.common.modules.store.ShopMchEntry; +import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.components.TaskService; import com.suisung.mall.shop.esign.mapper.EsignContractMapper; @@ -32,11 +34,8 @@ import com.suisung.mall.shop.esign.utils.comm.EsignHttpHelper; import com.suisung.mall.shop.esign.utils.comm.EsignHttpResponse; import com.suisung.mall.shop.esign.utils.enums.EsignRequestType; import com.suisung.mall.shop.esign.utils.exception.EsignDemoException; -import com.suisung.mall.shop.lakala.service.LakalaApiService; -import com.suisung.mall.shop.lakala.service.LklLedgerMemberService; import com.suisung.mall.shop.page.service.OssService; import com.suisung.mall.shop.store.service.ShopMchEntryService; -import com.suisung.mall.shop.store.service.ShopStoreBaseService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -91,18 +90,6 @@ public class EsignContractServiceImpl extends BaseServiceImpl ret = innerSignFlowCreateByFile(mchMobile); + public CommonResult signFlowCreateByFile(Integer storeId) { + Pair ret = innerSignFlowCreateByFile(storeId); if (!ret.getFirst()) { return CommonResult.failed(ret.getSecond()); } @@ -179,21 +166,25 @@ public class EsignContractServiceImpl extends BaseServiceImpl innerSignFlowCreateByFile(String mchMobile) { - //String userId = "0"; - - if (StrUtil.isBlank(mchMobile)) { + public Pair innerSignFlowCreateByFile(Integer storeId) { + if (CheckUtil.isEmpty(storeId)) { return Pair.of(false, "缺少必要参数!"); } - EsignContract esignContract = getEsignContractByMchMobile(mchMobile); + // 组织和填充商家店铺的模版数据 + Boolean isFill = esignContractFillingFileService.fillDocTemplate(storeId); + if (!isFill) { + return Pair.of(false, "合同信息未准备好,请检查商家入驻手续是否已完成!"); + } + + EsignContract esignContract = getEsignContractByStoreId(storeId); if (esignContract == null) { return Pair.of(false, "未找到商家合同信息"); } // 检查商户入驻信息是否被审核通过 // 检查店铺是否已经申请过入驻 - Integer apprStatus = shopMchEntryService.getApprovalStatus(mchMobile); + Integer apprStatus = shopMchEntryService.getApprovalStatus(esignContract.getMch_mobile()); if (!CommonConstant.MCH_APPR_STA_PASS.equals(apprStatus)) { return Pair.of(false, "请先审核商家入驻信息"); } @@ -254,108 +245,168 @@ public class EsignContractServiceImpl extends BaseServiceImpl>> {}", requestBody); log.debug("签署流程结束通知:header >>> {}", request.getParameterMap()); - //异步通知获取到的header头中的签名值:X-Tsign-Open-App-Id + // 1. 验证请求头参数完整性 String reqAppId = request.getHeader("X-Tsign-Open-App-Id"); - //异步通知获取到的header头中的签名值:X-Tsign-Open-SIGNATURE - String signture = request.getHeader("X-Tsign-Open-SIGNATURE"); - //异步通知获取到的header头中的时间戳:X-Tsign-Open-TIMESTAMP + String signature = request.getHeader("X-Tsign-Open-SIGNATURE"); String timestamp = request.getHeader("X-Tsign-Open-TIMESTAMP"); - if (StrUtil.isBlank(reqAppId) || StrUtil.isBlank(signture) || StrUtil.isBlank(timestamp)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new JSONObject().put("code", 400).put("msg", "缺少必要参数").toString()); + if (StrUtil.isBlank(reqAppId) || StrUtil.isBlank(signature) || StrUtil.isBlank(timestamp)) { + log.warn("e签宝异步通知缺少必要参数: reqAppId={}, signature={}, timestamp={}", reqAppId, signature, timestamp); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "缺少必要参数").toString()); } + // 2. 验证AppId是否匹配 if (!reqAppId.equals(appId)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new JSONObject().put("code", 400).put("msg", "appId 有误").toString()); + log.warn("e签宝异步通知AppId不匹配: 请求AppId={}, 配置AppId={}", reqAppId, appId); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "appId 有误").toString()); } - //按照规则进行加密 + // 3. 验证签名 String signData = timestamp + requestBody; String mySignature = getSignature(signData, appSecret, "HmacSHA256", "UTF-8"); - log.debug("加密出来的签名值:----------->>>>>>" + mySignature); - log.debug("header里面的签名值:---------->>>>>>" + signture); - if (!mySignature.equals(signture)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new JSONObject().put("code", 400).put("msg", "签名校验失败").toString()); + + // 签名生成失败处理 + if (mySignature == null) { + log.error("生成签名失败,signData: {}", signData); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "签名生成失败").toString()); + } + + log.debug("加密出来的签名值:----------->>>>>> {}", mySignature); + log.debug("header里面的签名值:---------->>>>>> {}", signature); + + if (!mySignature.equals(signature)) { + log.warn("e签宝异步通知签名校验失败: 计算签名={}, 请求签名={}", mySignature, signature); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "签名校验失败").toString()); + } + + // 4. 解析请求体数据 + JSONObject reqBodyJSON; + try { + reqBodyJSON = JSONUtil.parseObj(requestBody); + } catch (Exception e) { + log.error("解析e签宝异步通知请求体失败: requestBody={}", requestBody, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "请求体格式错误").toString()); } - // 处理业务逻辑 - JSONObject reqBodyJSON = JSONUtil.parseObj(requestBody); String action = reqBodyJSON.getStr("action"); String signFlowId = reqBodyJSON.getStr("signFlowId"); Integer signResult = reqBodyJSON.getInt("signResult"); + if (StrUtil.isBlank(action) || StrUtil.isBlank(signFlowId)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new JSONObject().put("code", 400).put("msg", "返回数据有误").toString()); + log.warn("e签宝异步通知缺少必要业务参数: action={}, signFlowId={}", action, signFlowId); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "返回数据有误").toString()); } - // 获取合同签署记录 - EsignContract esignContract = baseMapper.selectOne(new QueryWrapper().eq("sign_flow_id", signFlowId)); - if (esignContract == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new JSONObject().put("code", 400).put("msg", "获取不到合同记录").toString()); + // 5. 获取合同签署记录 + EsignContract esignContract; + try { + esignContract = baseMapper.selectOne(new QueryWrapper().eq("sign_flow_id", signFlowId)); + if (esignContract == null) { + log.warn("未找到对应的合同记录: signFlowId={}", signFlowId); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "获取不到合同记录").toString()); + } + } catch (Exception e) { + log.error("查询合同记录异常: signFlowId={}", signFlowId, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new JSONObject().put("code", 500).put("msg", "查询合同记录异常").toString()); } log.debug("签署流程结束通知:action >>> {}", action); - if (CommonConstant.CONTRACT_SIGN_STA_FINISH.equals(esignContract.getSign_flow_status()) && StrUtil.isNotEmpty(esignContract.getLocal_contract_url())) { - // 已经签署完毕,不用在更改状态 + + // 6. 如果合同已经完成且已有本地文件URL,则直接返回成功 + if (CommonConstant.CONTRACT_SIGN_STA_FINISH.equals(esignContract.getSign_flow_status()) + && StrUtil.isNotEmpty(esignContract.getLocal_contract_url())) { + log.debug("合同已处理完成,无需重复处理: signFlowId={}", signFlowId); return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString()); } - // 获取正式盖章合同文件,上传到 oss 服务器,更状态,保存数据 - if (action.equals("SIGN_FLOW_COMPLETE")) {// 签署流程完毕 - log.debug("签署流程完毕,开始处理业务逻辑"); - // 获取正式盖章合同文件地址 - String downloadUrl = getSignedContractFileUrl(signFlowId); + // 7. 根据不同动作类型处理业务逻辑 + try { + // 签署流程完毕 + if ("SIGN_FLOW_COMPLETE".equals(action)) { + log.debug("签署流程完毕,开始处理业务逻辑: signFlowId={}", signFlowId); - // 更新合同流程状态和文件地址 - boolean success = updateContractFlowStatusAndFileUrlBySignFlowId(signFlowId, CommonConstant.CONTRACT_SIGN_STA_FINISH, downloadUrl); - if (success && StrUtil.isNotBlank(downloadUrl)) { - - // 1、(电子合同)给商家申请分账功能使用;务必检查是否申请过?申请过忽略 - Pair retPair = lakalaApiService.innerApplyLedgerMer("", false); - if (!retPair.getFirst()) { - log.error("商家申请分账业务异常:{}", retPair.getSecond()); + // 获取正式盖章合同文件地址 + String downloadUrl = getSignedContractFileUrl(signFlowId); + if (StrUtil.isBlank(downloadUrl)) { + log.warn("获取签署完成的合同文件URL失败: signFlowId={}", signFlowId); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new JSONObject().put("code", 500).put("msg", "获取合同文件失败").toString()); } - // TODO mchId 必填字段,更新商家的hasEsigned状态=1 - shopMchEntryService.updateMulStatus(0L, "", 1, 0, 0, 0, 0, 0, CommonConstant.MCH_APPR_STA_LKL_PADDING); + // 更新合同流程状态和文件地址 + boolean success = updateContractFlowStatusAndFileUrlBySignFlowId( + signFlowId, + CommonConstant.CONTRACT_SIGN_STA_FINISH, + downloadUrl); + if (success) { + log.info("合同签署完成处理成功: signFlowId={}", signFlowId); + return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString()); + } else { + log.error("更新合同流程状态失败: signFlowId={}", signFlowId); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new JSONObject().put("code", 500).put("msg", "更新合同状态失败").toString()); + } + } + // 签署方签署结果通知(含拒签) + else if ("SIGN_MISSON_COMPLETE".equals(action) && ObjectUtil.isNotEmpty(signResult)) { + Integer signFlowStatus = null; + + // 根据签署结果确定合同状态 + if (Integer.valueOf(2).equals(signResult)) { + signFlowStatus = CommonConstant.CONTRACT_SIGN_STA_PARTIALLY; + } else if (Integer.valueOf(4).equals(signResult)) { + signFlowStatus = CommonConstant.CONTRACT_SIGN_STA_REJECT; + } + + if (signFlowStatus == null) { + log.warn("未知的签署结果类型: signResult={}", signResult); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new JSONObject().put("code", 400).put("msg", "未知的签署结果").toString()); + } + + // 更新合同流程状态 + boolean success = updateContractFlowStatusAndFileUrlBySignFlowId(signFlowId, signFlowStatus, ""); + if (success) { + log.info("签署任务完成处理成功: signFlowId={}, signResult={}, status={}", + signFlowId, signResult, signFlowStatus); + return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString()); + } else { + log.error("更新合同流程状态失败: signFlowId={}, signResult={}", signFlowId, signResult); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new JSONObject().put("code", 500).put("msg", "更新合同状态失败").toString()); + } + } + // 其他情况,记录日志但不处理 + else { + log.debug("签署流程未完成或未知动作类型,不做处理: action={}, signFlowId={}", action, signFlowId); return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString()); } - } else if (action.equals("SIGN_MISSON_COMPLETE") && ObjectUtil.isNotEmpty(signResult)) {// 签署方-签署结果(含拒签)通知 - Integer signFlowStatus = null; - if (signResult.equals(2)) { - signFlowStatus = CommonConstant.CONTRACT_SIGN_STA_PARTIALLY; - } else if (signResult.equals(4)) { - signFlowStatus = CommonConstant.CONTRACT_SIGN_STA_REJECT; - } - // 更新合同流程状态和文件地址 - boolean success = updateContractFlowStatusAndFileUrlBySignFlowId(signFlowId, signFlowStatus, ""); - if (success) { - return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString()); - } - } else { - log.debug("签署流程未完成,不做处理"); + } catch (Exception e) { + log.error("处理e签宝异步通知异常: action={}, signFlowId={}", action, signFlowId, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new JSONObject().put("code", 500).put("msg", "处理通知异常").toString()); } - - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new JSONObject().put("code", 400).put("msg", "未更新数据!").toString()); } + /** * 管理员查看已签署的电子合同文件 * - * @param mchMobile + * @param storeId * @return */ @Override - public CommonResult getSignedContactFile(String mchMobile) { - String userId = "0"; - -// UserDto user = getCurrentUser(); -// if (!user.isAdmin()) { -// return CommonResult.failed("权限不足!"); -// } -// userId = user.getId().toString(); - - EsignContract esignContract = getEsignContractByMchMobile(mchMobile); + public CommonResult getSignedContactFile(Integer storeId) { + EsignContract esignContract = getEsignContractByStoreId(storeId); if (esignContract == null) { return CommonResult.success(null, "未找到商家合同信息"); } @@ -583,22 +634,86 @@ public class EsignContractServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("mch_mobile", mchMobile); - queryWrapper.eq("status", CommonConstant.Enable); - List esignContractList = this.list(queryWrapper); - if (CollectionUtil.isEmpty(esignContractList)) { + // 参数校验 + if (StrUtil.isBlank(mchMobile)) { + log.warn("查询合同信息失败:商家手机号为空"); return null; } - return esignContractList.get(0); + try { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("mch_mobile", mchMobile); + queryWrapper.eq("status", CommonConstant.Enable); + + return findOne(queryWrapper); + } catch (Exception e) { + log.error("根据商家手机号查询合同信息异常,手机号: {}", mchMobile, e); + return null; + } } + /** + * 根据店铺Id,获取一条合同信息 + * + * @param storeId 店铺ID + * @return EsignContract 合同信息对象,若未找到则返回null + */ + @Override + public EsignContract getEsignContractByStoreId(Integer storeId) { + // 参数校验 + if (storeId == null) { + log.warn("查询合同信息失败:店铺ID为空"); + return null; + } + + try { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("store_id", storeId); + queryWrapper.eq("status", CommonConstant.Enable); + + return findOne(queryWrapper); + } catch (Exception e) { + log.error("根据店铺ID查询合同信息异常,店铺ID: {}", storeId, e); + return null; + } + } + + /** + * 根据店铺Id,获取合同状态和下载地址 + * + * @param storeId + * @return + */ + @Override + public EsignContract getEsignContractStatusUrl(Integer storeId) { + // 参数校验 + if (storeId == null) { + log.warn("查询合同状态和URL失败:店铺ID为空"); + return null; + } + + try { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(EsignContract::getStore_id, storeId) + .eq(EsignContract::getStatus, CommonConstant.Enable) + .eq(EsignContract::getSign_flow_status, CommonConstant.CONTRACT_SIGN_STA_FINISH) + .isNotNull(EsignContract::getLocal_contract_url) + .ne(EsignContract::getLocal_contract_url, "") + .select(EsignContract::getSign_flow_status, EsignContract::getLocal_contract_url); + + return findOne(queryWrapper); + } catch (Exception e) { + log.error("根据店铺ID查询合同状态和URL异常,店铺ID: {}", storeId, e); + return null; + } + } + + @Override public EsignContract getEsignContractBySignFlowId(String signFlowId) { QueryWrapper queryWrapper = new QueryWrapper<>(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java index 6aa55a76..6c3d3c7a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java @@ -149,12 +149,7 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl esignPlatformInfos = list(queryWrapper); - if (CollectionUtil.isEmpty(esignPlatformInfos)) { - return null; - } - - return esignPlatformInfos.get(0); + return findOne(queryWrapper); } /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 6ba8d32b..a3ea4618 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -5390,6 +5390,18 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl orderItems = shopOrderItemService.find(new QueryWrapper().eq("order_id", orderId)); @@ -2996,16 +2996,16 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl= 3) { -// cityName = areaNames[areaNames.length - 1]; -// } else { -// cityName = shopMchEntry.getStore_area().replace("/", ""); -// } -// } else { -// cityName = addressParseResultTO.getCity(); -// } -// -// // 如果解析后城市名为空,使用默认值 -// if (StrUtil.isBlank(cityName)) { -// cityName = "桂平市"; -// logger.warn("[顺丰] 城市名为空,使用默认城市: {}", cityName); -// } else { -// logger.debug("[顺丰] 解析得到城市名: {}", cityName); -// } -// -// // 为了其他顺丰店同名,店铺名称加上[门店ID]; 如:xxxx[xxxx] 聚万家生鲜超市[69] -// String shopStoreName = String.format("%s[%s]", shopMchEntry.getStore_name(), shopMchEntry.getStore_id()); - // 调用创建店铺方法 Pair result = createSfExpressShop( mchId, Convert.toInt(shopMchEntry.getStore_id()), -// shopStoreName, -// cityName, -// storeAddress, shopMchEntry.getContact_name(), contactMobile, shopMchEntry.getStore_longitude(), @@ -718,77 +686,92 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { * 取消订单 * * @param params 综合参数,请参考:https://openic.sf-express.com/open/api/docs/index/#/apidoc - * @return + * @return ThirdApiRes 取消订单结果 */ @Override @Transactional public ThirdApiRes cancelOrder(Map params) { - // TODO 检验用户权限 + logger.info("[顺丰] 开始取消订单流程"); + // 1. 参数校验 if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) { + logger.warn("[顺丰] 取消订单参数校验失败: 参数为空或缺少order_id"); return new ThirdApiRes().fail(1003, "请求参数有误!"); } - // 转换 json 字符串参数 - String sfOrderId = params.get("order_id").toString(); // 这是顺丰的订单号,不是商城的订单号 - params.putAll(buildCommonParams()); + try { + // 2. 获取顺丰订单号 + String sfOrderId = params.get("order_id").toString(); + logger.debug("[顺丰] 准备取消订单: sfOrderId={}", sfOrderId); - String paramJSON = JsonUtil.toJSONString(params); + // 3. 添加公共参数 + params.putAll(buildCommonParams()); + String paramJSON = JsonUtil.toJSONString(params); - // 根据参数生成请求签名 - String send_url = buildUrl("cancelorder", paramJSON); - String retRespStr = HttpUtil.post(send_url, paramJSON); - if (StrUtil.isBlank(retRespStr)) { - logger.error("顺丰同城:取消订单异常,无返回值!"); - return new ThirdApiRes().fail(2, "顺丰同城:无返回值!"); + // 4. 调用顺丰取消订单接口 + String sendUrl = buildUrl("cancelorder", paramJSON); + logger.debug("[顺丰] 调用取消订单接口: url={}, params={}", sendUrl, paramJSON); + + String responseStr = HttpUtil.post(sendUrl, paramJSON); + if (StrUtil.isBlank(responseStr)) { + logger.error("[顺丰] 取消订单接口调用失败: 无返回值, sfOrderId={}", sfOrderId); + return new ThirdApiRes().fail(2, "顺丰同城:无返回值!"); + } + + // 5. 解析接口响应 + ThirdApiRes sfExpressApiRes = JsonUtil.json2object(responseStr, ThirdApiRes.class); + if (sfExpressApiRes == null) { + logger.error("[顺丰] 取消订单接口响应解析失败: {}, sfOrderId={}", responseStr, sfOrderId); + return new ThirdApiRes().fail(2, "顺丰同城:响应解析失败!"); + } + + // 6. 检查接口调用结果 + if (!sfExpressApiRes.getError_code().equals(0)) { + logger.error("[顺丰] 取消订单接口调用失败: errorCode={}, errorMsg={}, sfOrderId={}", + sfExpressApiRes.getError_code(), sfExpressApiRes.getError_msg(), sfOrderId); + return new ThirdApiRes().fail(2, sfExpressApiRes.getError_msg()); + } + + logger.info("[顺丰] 顺丰接口取消订单成功: sfOrderId={}", sfOrderId); + + // 7. 检查本地订单状态 + ShopStoreSfOrder existingOrder = shopStoreSfOrderService.getByShopOrderId(sfOrderId); + if (existingOrder == null) { + logger.error("[顺丰] 本地订单不存在: sfOrderId={}", sfOrderId); + return new ThirdApiRes().fail(2, "订单不存在!"); + } + + // 8. 检查订单是否已经取消 + if (existingOrder.getOrder_status() != null && + (existingOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELED) || + existingOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELING))) { + logger.info("[顺丰] 订单已处于取消状态,无需重复操作: sfOrderId={}, status={}", + sfOrderId, existingOrder.getOrder_status()); + return new ThirdApiRes().success("订单已取消过!"); + } + + // 9. 更新顺丰订单状态为已取消 + ShopStoreSfOrder updateOrder = new ShopStoreSfOrder(); + updateOrder.setSf_order_id(existingOrder.getSf_order_id()); + updateOrder.setOrder_status(StateCode.SF_ORDER_STATUS_CANCELED); + updateOrder.setStatus_desc("线上商城发起取消订单"); + + Boolean updateSuccess = shopStoreSfOrderService.updateShopStoreSfOrderStatus(updateOrder); + if (!updateSuccess) { + logger.error("[顺丰] 更新本地订单状态失败: sfOrderId={}", sfOrderId); + throw new ApiException(_("取消顺丰订单失败!")); + } + + logger.info("[顺丰] 本地订单状态更新成功: sfOrderId={}", sfOrderId); + return sfExpressApiRes; + + } catch (Exception e) { + logger.error("[顺丰] 取消订单过程中发生异常: ", e); + return new ThirdApiRes().fail(-1, "系统异常: " + e.getMessage()); } - - ThirdApiRes sfExpressApiRes = JsonUtil.json2object(retRespStr, ThirdApiRes.class); - if (sfExpressApiRes == null) { - logger.error("顺丰同城:取消订单,返回值异常!{}", retRespStr); - return new ThirdApiRes().fail(2, "顺丰同城:无返回值!"); - } - - if (!sfExpressApiRes.getError_code().equals(0)) { - logger.error("顺丰同城:取消订单失败!{}", retRespStr); - return new ThirdApiRes().fail(2, sfExpressApiRes.getError_msg()); - } - - // 判断订单的状态,是否已经取消了?已取消,不再执行 - ShopStoreSfOrder shopStoreSfOrderExist = shopStoreSfOrderService.getByShopOrderId(sfOrderId); - if (shopStoreSfOrderExist == null) { - return new ThirdApiRes().fail(2, "订单有误!"); - } - - if (shopStoreSfOrderExist.getOrder_status() != null - && (shopStoreSfOrderExist.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELED) || - (shopStoreSfOrderExist.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELING)))) { - return new ThirdApiRes().success("订单已取消过!"); - } - -// // 更改商城订单状态为:已取消,注意事务问题 -// List orderList = new ArrayList<>(); -// orderList.add(shopStoreSfOrderExist.getShop_order_id()); - // 取消订单, 流程:订单状态;积分、众宝、库存、礼包、优惠券 有就统统退还 -// Boolean success = shopOrderReturnService.sfExpressExpiredForceRefund(shopStoreSfOrderExist.getShop_order_id()); // 不检查订单付款状态 -// if (!success) { -// throw new ApiException(I18nUtil._("取消商家订单失败!")); -// } - - // 更改顺丰的订单状态 - ShopStoreSfOrder shopStoreSfOrder = new ShopStoreSfOrder(); - shopStoreSfOrder.setSf_order_id(shopStoreSfOrderExist.getSf_order_id()); - shopStoreSfOrder.setOrder_status(StateCode.SF_ORDER_STATUS_CANCELED); - shopStoreSfOrder.setStatus_desc("线上商城发起取消订单"); - Boolean success = shopStoreSfOrderService.updateShopStoreSfOrderStatus(shopStoreSfOrder); - if (!success) { - throw new ApiException(_("取消顺丰订单失败!")); - } - - - return sfExpressApiRes; } + /** * 订单加小费,订单创建后,骑士未接单的情况下通过该接口对订单进行加小费,促进订单接单,截止订单完成前,都可以对订单加小费 * @@ -1170,10 +1153,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { String order_id = shopStoreSfOrder.getShop_order_id(); itemQueryWrapper.eq("order_id", order_id); List order_item_rows = shopOrderItemService.find(itemQueryWrapper); - ShopOrderBase shopOrderBase=shopOrderBaseService.get(order_id); - String saleTimeStr=null; - if(null!=shopOrderBase){ - saleTimeStr= String.valueOf(shopOrderBase.getOrder_time().getTime()); + ShopOrderBase shopOrderBase = shopOrderBaseService.get(order_id); + String saleTimeStr = null; + if (null != shopOrderBase) { + saleTimeStr = String.valueOf(shopOrderBase.getOrder_time().getTime()); } if (picking(order_item_rows)) { logger.info("顺丰发货商品扣减库存成功"); @@ -1183,12 +1166,12 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - String mapKey=item_src_id + "-" + shopStoreSfOrder.getShop_order_id()+"-"+shopOrderItem.getOrder_item_unit_price(); - if(StringUtils.isNotEmpty(saleTimeStr)){ - mapKey=mapKey+"-"+saleTimeStr; + String mapKey = item_src_id + "-" + shopStoreSfOrder.getShop_order_id() + "-" + shopOrderItem.getOrder_item_unit_price(); + if (StringUtils.isNotEmpty(saleTimeStr)) { + mapKey = mapKey + "-" + saleTimeStr; } stockDeltaMap.put(mapKey, -order_item_quantity); - syncThirdDataService.incrProductStockToRedis(stockDeltaMap,null); + syncThirdDataService.incrProductStockToRedis(stockDeltaMap, null); } } //出库扣减思迅库存end @@ -1356,9 +1339,9 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Map stockDeltaMap = new HashMap<>(); String item_src_id = shopOrderItem.getItem_src_id(); Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); - String mapKey=item_src_id + "-" + shopOrderItem.getOrder_id()+"-"+shopOrderItem.getOrder_item_unit_price()+"-"+shopOrderBase.getOrder_time().getTime(); + String mapKey = item_src_id + "-" + shopOrderItem.getOrder_id() + "-" + shopOrderItem.getOrder_item_unit_price() + "-" + shopOrderBase.getOrder_time().getTime(); stockDeltaMap.put(mapKey, -order_item_quantity); - syncThirdDataService.incrProductStockToRedis(stockDeltaMap,null); + syncThirdDataService.incrProductStockToRedis(stockDeltaMap, null); } } return CommonResult.success("操作成功"); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java index 2aa1bf4f..6ffbd5cb 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java @@ -44,7 +44,7 @@ public class ShopMchEntryController extends BaseControllerImpl { @ApiOperation(value = "测试", notes = "测试") @RequestMapping(value = "/gencon", method = RequestMethod.POST) public Object fillDocTemplate() { - return esignContractFillingFileService.fillDocTemplate("13128997057", "91450881MADEQ92533"); + return esignContractFillingFileService.fillDocTemplate(57); } @ApiOperation(value = "店铺主营分类(类目)", notes = "店铺主营分类(类目)") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java index f1859fa4..40ce92cc 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java @@ -367,4 +367,12 @@ public interface ShopMchEntryService { * @return 包含ID路径和名称路径的字符串数组,格式为 [ID路径, 名称路径] */ String[] handleStoreDistrictInfo(String storeDistrict, String storeArea, String refStoreAddress); + + /** + * 根据店铺Id,获取拉卡拉的审核状态和下载地址 + * + * @param storeId + * @return + */ + ShopMchEntry getLklContractStatusUrl(Integer storeId); } \ No newline at end of file diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java index 0f5a945f..498727e8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java @@ -17,6 +17,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -2511,6 +2512,36 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopMchEntry::getStore_id, storeId) + .eq(ShopMchEntry::getStatus, CommonConstant.Enable) + .eq(ShopMchEntry::getApproval_status, CommonConstant.MCH_APPR_STA_PASS) + .isNotNull(ShopMchEntry::getContract_download_url) + .ne(ShopMchEntry::getContract_download_url, "") + .select(ShopMchEntry::getApproval_status, ShopMchEntry::getContract_download_url); + + return findOne(queryWrapper); + } catch (Exception e) { + log.error("根据店铺ID查询合同状态和URL异常,店铺ID: {}", storeId, e); + return null; + } + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java index cedc24aa..a941e594 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java @@ -33,6 +33,7 @@ import com.suisung.mall.common.modules.account.AccountUserInfo; import com.suisung.mall.common.modules.account.AccountUserSns; import com.suisung.mall.common.modules.base.*; import com.suisung.mall.common.modules.distribution.ShopDistributionPlantformUser; +import com.suisung.mall.common.modules.esign.EsignContract; import com.suisung.mall.common.modules.invoicing.InvoicingCustomerLevel; import com.suisung.mall.common.modules.invoicing.InvoicingWarehouseBase; import com.suisung.mall.common.modules.page.ShopPageBase; @@ -56,6 +57,7 @@ import com.suisung.mall.shop.base.service.ShopBaseStoreGradeService; import com.suisung.mall.shop.config.BaiduUtil; import com.suisung.mall.shop.distribution.service.ShopDistributionPlantformUserService; import com.suisung.mall.shop.entity.LocationBean; +import com.suisung.mall.shop.esign.service.EsignContractService; import com.suisung.mall.shop.invoicing.service.InvoicingCustomerLevelService; import com.suisung.mall.shop.invoicing.service.InvoicingWarehouseBaseService; import com.suisung.mall.shop.page.service.ShopPageBaseService; @@ -184,6 +186,11 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl items = (List) data.get("items"); //经营期限 + List store_ids = items.stream().map(s -> Convert.toInt(s.get("store_id"))).collect(Collectors.toList()); List store_info_rows = shopStoreInfoService.gets(store_ids); List subsite_ids = items.stream().map(s -> Convert.toInt(s.get("subsite_id"))).distinct().collect(Collectors.toList()); @@ -1481,6 +1489,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl store_analytics_rows = shopStoreAnalyticsService.gets(store_ids); List finalSubsite_rows = subsite_rows; @@ -1525,6 +1534,22 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl) data.get("items"), true)); @@ -1558,6 +1583,21 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl Date: Mon, 1 Dec 2025 17:42:27 +0800 Subject: [PATCH 63/81] =?UTF-8?q?=E5=8F=96=E6=B6=88=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E4=B9=9F=E8=A6=81=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E9=A1=BA=E4=B8=B0=E5=90=8C=E5=9F=8E=E7=9A=84=E9=85=8D=E9=80=81?= =?UTF-8?q?=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/impl/ShopOrderBaseServiceImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index a3ea4618..a3e0155c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -5391,14 +5391,20 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl Date: Tue, 2 Dec 2025 17:21:30 +0800 Subject: [PATCH 64/81] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/order/service/impl/ShopOrderBaseServiceImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index a3e0155c..97d9b323 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -4495,6 +4495,11 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl items = (List) data.get("items"); From 7326d0505f1eb114ae21fa2f0e0297b21f872140 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Tue, 2 Dec 2025 23:45:46 +0800 Subject: [PATCH 65/81] =?UTF-8?q?=E5=95=86=E5=AE=B6=E9=A2=84=E8=AE=A1?= =?UTF-8?q?=E6=94=B6=E5=85=A5=E6=97=A0=E9=9C=80=E5=87=8F=20=E6=8B=89?= =?UTF-8?q?=E5=8D=A1=E6=8B=89=E5=B9=B3=E5=8F=B0=E8=B4=B9=EF=BC=8C=E9=85=8D?= =?UTF-8?q?=E9=80=81=E8=B4=B9=E8=AE=A1=E7=AE=97=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=B9=B3=E5=8F=B0=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/modules/store/ShopStoreSameCityTransportBase.java | 3 +++ .../src/main/resources/mapper/order/ShopOrderBaseMapper.xml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java index 00c097b6..8204ee6e 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java @@ -43,6 +43,9 @@ public class ShopStoreSameCityTransportBase implements Serializable { @TableId(value = "transport_base_id", type = IdType.AUTO) private Long transport_base_id; + @ApiModelProperty(value = "平台配送费设置?1-是;2-否") + private Integer is_platform; + @ApiModelProperty(value = "店铺ID") private Long store_id; diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml index b18acf8f..4e5a8bbf 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml @@ -819,8 +819,8 @@ (od.order_discount_amount + od.voucher_price + od.order_points_fee + od.order_adjust_fee) as total_discount_amount, - - (ob.order_product_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-order_shipping_fee_inner-lkl_fee+od.packing_fee) + + (ob.order_product_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-order_shipping_fee_inner+od.packing_fee) as order_income_amount, (od.platform_fee+lkl_fee) as platform_fee, od.packing_fee, From 46b27539b55d047ddc03c107619b7ac95ba7e6db Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 3 Dec 2025 10:42:03 +0800 Subject: [PATCH 66/81] =?UTF-8?q?=E6=8B=89=E5=8D=A1=E6=8B=89=E7=AD=BE?= =?UTF-8?q?=E7=BD=B2=E5=85=A5=E7=BD=91=E5=90=88=E5=90=8C=EF=BC=8C=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=B9=B3=E5=8F=B0=E7=9A=84=E5=85=AC=E5=8F=B8=E5=90=8D?= =?UTF-8?q?=E5=92=8C=E6=89=8B=E6=9C=BA=E5=8F=B7=EF=BC=8C=E5=A1=AB=E5=85=85?= =?UTF-8?q?=E5=90=88=E5=90=8C=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/EsignContractFillingFileServiceImpl.java | 10 ++++++++-- .../lakala/service/impl/LakalaApiServiceImpl.java | 14 +++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java index de141c64..cecc2b57 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java @@ -115,6 +115,11 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl header = EsignHttpHelper.signAndBuildSignAndJsonHeader( appId, appSecret, jsonParam, requestType.name(), apiAddr, debug); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java index 8f96e232..e4c8e546 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java @@ -27,6 +27,7 @@ import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.feignService.ShopService; +import com.suisung.mall.common.modules.esign.EsignPlatformInfo; import com.suisung.mall.common.modules.lakala.*; import com.suisung.mall.common.modules.order.ShopOrderLkl; import com.suisung.mall.common.modules.store.ShopMchEntry; @@ -54,6 +55,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -470,7 +472,17 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 7. 构建合同参数 LocalDate today = LocalDate.now(); String signDate = DateTimeUtils.formatLocalDate(today, "yyyy-MM-dd"); + + // 2. 获取平台方信息 String platformName = "桂平发发网络有限公司"; + String platMobile = "17777525395"; // 平台联系电话 + EsignPlatformInfo esignPlatformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, ""); + if (!ObjectUtils.isEmpty(esignPlatformInfo) + && StrUtil.isNotBlank(esignPlatformInfo.getLicense_company()) + && StrUtil.isNotBlank(esignPlatformInfo.getTelephone())) { + platformName = esignPlatformInfo.getLicense_company(); + platMobile = esignPlatformInfo.getTelephone(); + } JSONObject ecParams = new JSONObject(); ecParams.put("A1", isQy ? shopMchEntry.getBiz_license_company() : shopMchEntry.getAccount_holder_name()); @@ -511,7 +523,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { ecParams.put("D1", shopMchEntry.getBank_name()); ecParams.put("D2", signDate); ecParams.put("D4", platformName); - ecParams.put("D5", contractMobile); + ecParams.put("D5", platMobile); ecParams.put("D7", signDate); ecParams.put("D9", signDate); ecParams.put("D11", signDate); From 950b7b9b328a300fd5f973e86c402b4da2bdee14 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 3 Dec 2025 11:38:47 +0800 Subject: [PATCH 67/81] =?UTF-8?q?=E9=87=8D=E8=A6=81=EF=BC=9A=E5=88=86?= =?UTF-8?q?=E8=B4=A6=E8=AE=A1=E7=AE=97=E6=96=B9=E6=B3=95=E5=81=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=8C=E6=8B=89=E5=8D=A1=E6=8B=89=E6=89=8B=E7=BB=AD?= =?UTF-8?q?=E8=B4=B9=E7=94=B1=20=E4=BB=A3=E7=90=86=E5=95=86=E6=88=96?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=87=BA=EF=BC=8C=E5=95=86=E5=AE=B6=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E6=89=A3=E9=99=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/LklSeparateWithTotalAmountDTO.java | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java index be215f5f..8214e213 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java @@ -206,7 +206,16 @@ public class LklSeparateWithTotalAmountDTO { return SeparateResult.failure(errorMsg); } - // 6. 计算商家实际分账比例 + // 6. 根据指定规则调整各参与方分账金额 + Pair adjustResult = adjustAmountsWithLklAmount(); + if (!adjustResult.getFirst()) { + String errorMsg = "分账计算参数异常: " + adjustResult.getSecond(); + log.error(errorMsg); + this.errMsg = errorMsg; + return SeparateResult.failure(errorMsg); + } + + // 7. 计算商家实际分账比例 Pair mchResult = calculateActualMchRatio(); if (!mchResult.getFirst()) { String errorMsg = "分账计算参数异常: " + mchResult.getSecond(); @@ -231,6 +240,54 @@ public class LklSeparateWithTotalAmountDTO { } } + /** + * 根据指定规则调整各参与方分账金额 + * 如果拉卡拉分账金额lklAmount>0: + * 1. 如果agent2ndAmount>0 且大于lklAmount, 则agent2ndAmount=agent2ndAmount-lklAmount,mchAmount=mchAmount+lklAmount + * 2. 如果agent2ndAmount<=0 但 agent1stAmount>0 且大于lklAmount, 则agent1stAmount=agent1stAmount-lklAmount,mchAmount=mchAmount+lklAmount + * 3. 如果agent2ndAmount<=0 且 agent1stAmount<=0,但 platAmount>0 且大于等于lklAmount, 则 platAmount=platAmount-lklAmount,mchAmount=mchAmount+lklAmount + * + * @return Pair Boolean表示是否成功,String为错误信息 + */ + private Pair adjustAmountsWithLklAmount() { + try { + // 只有当拉卡拉分账金额大于0时才执行调整逻辑 + if (lklAmount != null && lklAmount > 0) { + int adjustment = lklAmount; // 需要调整的金额 + + // 情况1: 如果agent2ndAmount>0 且大于lklAmount + if (agent2ndAmount != null && agent2ndAmount > 0 && agent2ndAmount > adjustment) { + agent2ndAmount -= adjustment; + mchAmount += adjustment; + log.debug("调整二级代理商分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); + } + // 情况2: 如果agent2ndAmount<=0 但 agent1stAmount>0 且大于lklAmount + else if ((agent2ndAmount == null || agent2ndAmount <= 0) && + agent1stAmount != null && agent1stAmount > 0 && agent1stAmount > adjustment) { + agent1stAmount -= adjustment; + mchAmount += adjustment; + log.debug("调整一级代理商分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); + } + // 情况3: 如果agent2ndAmount<=0 且 agent1stAmount<=0,但 platAmount>0 且大于等于lklAmount + else if ((agent2ndAmount == null || agent2ndAmount <= 0) && + (agent1stAmount == null || agent1stAmount <= 0) && + platAmount != null && platAmount > 0 && platAmount >= adjustment) { + platAmount -= adjustment; + mchAmount += adjustment; + log.debug("调整平台分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); + } + // 其他情况不作调整 + else { + log.debug("不满足调整条件,无需调整各参与方分账金额"); + } + } + + return Pair.of(true, ""); + } catch (Exception e) { + return Pair.of(false, "调整分账金额时发生异常: " + e.getMessage()); + } + } + /** * 校验必要参数 * From b1f401ff8153b1cab7c56bd867bfdf39600791ab Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 3 Dec 2025 11:46:26 +0800 Subject: [PATCH 68/81] =?UTF-8?q?=E9=87=8D=E8=A6=81=EF=BC=9A=E5=88=86?= =?UTF-8?q?=E8=B4=A6=E8=AE=A1=E7=AE=97=E6=96=B9=E6=B3=95=E5=81=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=8C=E6=8B=89=E5=8D=A1=E6=8B=89=E6=89=8B=E7=BB=AD?= =?UTF-8?q?=E8=B4=B9=E7=94=B1=20=E4=BB=A3=E7=90=86=E5=95=86=E6=88=96?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=87=BA=EF=BC=8C=E5=95=86=E5=AE=B6=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E6=89=A3=E9=99=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/LklSeparateWithTotalAmountDTO.java | 107 +++++++++--------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java index 8214e213..fe328f22 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java @@ -34,9 +34,9 @@ import java.math.RoundingMode; public class LklSeparateWithTotalAmountDTO { // 商家最低分账比例阈值 20% - private static final BigDecimal MCH_RATIO_THRESHOLD = BigDecimal.valueOf(0.2); + private static final BigDecimal MIN_MERCHANT_RATIO_THRESHOLD = BigDecimal.valueOf(0.2); // 默认平台比例 1% - private static final BigDecimal DEFAULT_PLAT_RATIO = BigDecimal.valueOf(0.01); + private static final BigDecimal DEFAULT_PLATFORM_RATIO = BigDecimal.valueOf(0.01); // 基础金额属性 private Integer totalSeparateAmount; // 分账总金额(分) @@ -240,54 +240,6 @@ public class LklSeparateWithTotalAmountDTO { } } - /** - * 根据指定规则调整各参与方分账金额 - * 如果拉卡拉分账金额lklAmount>0: - * 1. 如果agent2ndAmount>0 且大于lklAmount, 则agent2ndAmount=agent2ndAmount-lklAmount,mchAmount=mchAmount+lklAmount - * 2. 如果agent2ndAmount<=0 但 agent1stAmount>0 且大于lklAmount, 则agent1stAmount=agent1stAmount-lklAmount,mchAmount=mchAmount+lklAmount - * 3. 如果agent2ndAmount<=0 且 agent1stAmount<=0,但 platAmount>0 且大于等于lklAmount, 则 platAmount=platAmount-lklAmount,mchAmount=mchAmount+lklAmount - * - * @return Pair Boolean表示是否成功,String为错误信息 - */ - private Pair adjustAmountsWithLklAmount() { - try { - // 只有当拉卡拉分账金额大于0时才执行调整逻辑 - if (lklAmount != null && lklAmount > 0) { - int adjustment = lklAmount; // 需要调整的金额 - - // 情况1: 如果agent2ndAmount>0 且大于lklAmount - if (agent2ndAmount != null && agent2ndAmount > 0 && agent2ndAmount > adjustment) { - agent2ndAmount -= adjustment; - mchAmount += adjustment; - log.debug("调整二级代理商分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); - } - // 情况2: 如果agent2ndAmount<=0 但 agent1stAmount>0 且大于lklAmount - else if ((agent2ndAmount == null || agent2ndAmount <= 0) && - agent1stAmount != null && agent1stAmount > 0 && agent1stAmount > adjustment) { - agent1stAmount -= adjustment; - mchAmount += adjustment; - log.debug("调整一级代理商分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); - } - // 情况3: 如果agent2ndAmount<=0 且 agent1stAmount<=0,但 platAmount>0 且大于等于lklAmount - else if ((agent2ndAmount == null || agent2ndAmount <= 0) && - (agent1stAmount == null || agent1stAmount <= 0) && - platAmount != null && platAmount > 0 && platAmount >= adjustment) { - platAmount -= adjustment; - mchAmount += adjustment; - log.debug("调整平台分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); - } - // 其他情况不作调整 - else { - log.debug("不满足调整条件,无需调整各参与方分账金额"); - } - } - - return Pair.of(true, ""); - } catch (Exception e) { - return Pair.of(false, "调整分账金额时发生异常: " + e.getMessage()); - } - } - /** * 校验必要参数 * @@ -379,7 +331,7 @@ public class LklSeparateWithTotalAmountDTO { private Pair calculateDefaultRatios() { // 如果平台比例无效,设置默认值0.01 if (platRatio == null || platRatio.compareTo(BigDecimal.ZERO) <= 0) { - platRatio = DEFAULT_PLAT_RATIO; + platRatio = DEFAULT_PLATFORM_RATIO; } return Pair.of(true, ""); @@ -479,6 +431,53 @@ public class LklSeparateWithTotalAmountDTO { return Pair.of(true, ""); } + /** + * 根据指定规则调整各参与方分账金额 + * 如果拉卡拉分账金额lklAmount>0: + * 1. 如果agent2ndAmount>0 且大于lklAmount, 则agent2ndAmount=agent2ndAmount-lklAmount,mchAmount=mchAmount+lklAmount + * 2. 如果agent2ndAmount<=0 但 agent1stAmount>0 且大于lklAmount, 则agent1stAmount=agent1stAmount-lklAmount,mchAmount=mchAmount+lklAmount + * 3. 如果agent2ndAmount<=0 且 agent1stAmount<=0,但 platAmount>0 且大于等于lklAmount, 则 platAmount=platAmount-lklAmount,mchAmount=mchAmount+lklAmount + * + * @return Pair Boolean表示是否成功,String为错误信息 + */ + private Pair adjustAmountsWithLklAmount() { + try { + // 只有当拉卡拉分账金额大于0时才执行调整逻辑 + if (lklAmount != null && lklAmount > 0) { + int adjustment = lklAmount; // 需要调整的金额 + + // 情况1: 如果agent2ndAmount>0 且大于lklAmount + if (agent2ndAmount != null && agent2ndAmount > 0 && agent2ndAmount > adjustment) { + agent2ndAmount -= adjustment; + mchAmount += adjustment; + log.debug("调整二级代理商分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); + } + // 情况2: 如果agent2ndAmount<=0 但 agent1stAmount>0 且大于lklAmount + else if ((agent2ndAmount == null || agent2ndAmount <= 0) && + agent1stAmount != null && agent1stAmount > 0 && agent1stAmount > adjustment) { + agent1stAmount -= adjustment; + mchAmount += adjustment; + log.debug("调整一级代理商分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); + } + // 情况3: 如果agent2ndAmount<=0 且 agent1stAmount<=0,但 platAmount>0 且大于等于lklAmount + else if ((agent2ndAmount == null || agent2ndAmount <= 0) && + (agent1stAmount == null || agent1stAmount <= 0) && + platAmount != null && platAmount > 0 && platAmount >= adjustment) { + platAmount -= adjustment; + mchAmount += adjustment; + log.debug("调整平台分账金额: 减少{},商家分账金额增加{}", adjustment, adjustment); + } + // 其他情况不作调整 + else { + log.debug("不满足调整条件,无需调整各参与方分账金额"); + } + } + + return Pair.of(true, ""); + } catch (Exception e) { + return Pair.of(false, "调整分账金额时发生异常: " + e.getMessage()); + } + } /** * 计算商家实际分账比例 @@ -492,9 +491,9 @@ public class LklSeparateWithTotalAmountDTO { .divide(BigDecimal.valueOf(totalSeparateAmount), 6, RoundingMode.HALF_UP); // 如果计算出的实际比例低于阈值,打印日志并返回错误 - if (mchRatio.compareTo(MCH_RATIO_THRESHOLD) < 0) { + if (mchRatio.compareTo(MIN_MERCHANT_RATIO_THRESHOLD) < 0) { String errorMsg = String.format("警告: 商家实际分账比例低于阈值,当前比例: %s,阈值: %s", - mchRatio.toPlainString(), MCH_RATIO_THRESHOLD.toPlainString()); + mchRatio.toPlainString(), MIN_MERCHANT_RATIO_THRESHOLD.toPlainString()); log.warn(errorMsg); return Pair.of(false, errorMsg); } @@ -668,4 +667,4 @@ public class LklSeparateWithTotalAmountDTO { return new SeparateResult(Boolean.TRUE, data, errMsg != null ? errMsg : ""); } } -} +} \ No newline at end of file From 28e5b83f6ce531e1314fbe477a364e3a38c1b06a Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Wed, 3 Dec 2025 17:50:55 +0800 Subject: [PATCH 69/81] =?UTF-8?q?=E5=90=8C=E5=9F=8E=E6=89=93=E7=A5=A8?= =?UTF-8?q?=E6=9C=BA=E6=89=93=E5=8D=B0=E5=AE=9E=E4=BD=93=E7=B1=BB=EF=BC=8C?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=94=B6=E8=B4=A7=E9=80=9A=E7=9F=A5=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../suisung/mall/common/api/StateCode.java | 7 ++-- .../mall/common/pojo/vo/OrderPrintVO.java | 8 +++-- .../common/pojo/vo/ShopStoreOrderPrintVO.java | 3 +- .../common/service/impl/CommonService.java | 36 ++++++++++++++++--- .../controller/mobile/LakalaController.java | 2 +- .../service/impl/LakalaApiServiceImpl.java | 8 +++++ .../impl/ShopOrderLogisticsServiceImpl.java | 4 ++- .../impl/ShopOrderReturnServiceImpl.java | 16 ++++++--- .../mapper/order/ShopOrderBaseMapper.xml | 4 +-- .../mapper/order/ShopOrderReturnMapper.xml | 5 +-- 10 files changed, 71 insertions(+), 22 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/api/StateCode.java b/mall-common/src/main/java/com/suisung/mall/common/api/StateCode.java index ec853b84..b4613ac9 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/api/StateCode.java +++ b/mall-common/src/main/java/com/suisung/mall/common/api/StateCode.java @@ -15,9 +15,8 @@ public class StateCode { public static final int DELIVERY_TYPE_AIR_FREIGHT = 4; //货运(空运、水运、铁路运输、公路运输) public static final int DELIVERY_TYPE_SELF_PICK_UP = 5; // 自提(运费 0 元) public static final int DELIVERY_TYPE_EXP = 10; // 普通快递 - public static final int DELIVERY_TYPE_IN_STORE_SERVICE = 15; // 店铺配送 - public static final int DELIVERY_TYPE_SAME_CITY = 16;//顺丰同城配送 - public static final int DELIVERY_TYPE_STORE_BY_SELF = 17; // 商家(线下)自己配送 + public static final int DELIVERY_TYPE_IN_STORE_SERVICE = 15; // 店铺配送(运费 0 元) + public static final int DELIVERY_TYPE_SAME_CITY = 16;//同城配送 public static final Map DELIVERY_TYPE_MAP = new HashMap() { { @@ -28,7 +27,7 @@ public class StateCode { put(DELIVERY_TYPE_SELF_PICK_UP, "到店自提"); put(DELIVERY_TYPE_EXP, "普通快递"); put(DELIVERY_TYPE_IN_STORE_SERVICE, "店铺配送"); - put(DELIVERY_TYPE_SAME_CITY, "顺丰同城"); + put(DELIVERY_TYPE_SAME_CITY, "顺丰同城配送"); } }; diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java index d1f166ab..391929fa 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java @@ -65,9 +65,13 @@ public class OrderPrintVO implements Serializable { @Builder.Default private String payment_type_name = "微信支付"; - @ApiModelProperty(value = "配送渠道") + @ApiModelProperty(value = "配送方式ID") @Builder.Default - private String deliver_type_name = "顺丰同城"; + private Integer delivery_type_id = 16; + + @ApiModelProperty(value = "配送方式") + @Builder.Default + private String delivery_type_name = "顺丰同城"; @ApiModelProperty(value = "打包费") private BigDecimal packing_fee; diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java index b0b32204..ebe7aa53 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/ShopStoreOrderPrintVO.java @@ -68,7 +68,7 @@ public class ShopStoreOrderPrintVO implements Serializable { @ApiModelProperty(value = "支付方式") private String pay_type; - @ApiModelProperty(value = "配送来源") + @ApiModelProperty(value = "配送方式") private String shipper_type; @ApiModelProperty(value = "下单时间") @@ -105,7 +105,6 @@ public class ShopStoreOrderPrintVO implements Serializable { @ApiModelProperty(value = "实际应付款") private Long order_payment_amount; - // 订单商品详情信息 @ApiModelProperty(value = "订单商品详情信息") private OrderItemPrintVO order_items; diff --git a/mall-common/src/main/java/com/suisung/mall/common/service/impl/CommonService.java b/mall-common/src/main/java/com/suisung/mall/common/service/impl/CommonService.java index 2ca316e6..47eeb7f2 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/service/impl/CommonService.java +++ b/mall-common/src/main/java/com/suisung/mall/common/service/impl/CommonService.java @@ -17,6 +17,7 @@ import com.suisung.mall.common.constant.CommonConstant; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.Objects; import java.util.regex.Pattern; @Slf4j @@ -76,10 +77,37 @@ public class CommonService { return false; } - // 普通配送是指除了同城配送、自提和到店服务之外的配送方式 - return !deliveryTypeId.equals(StateCode.DELIVERY_TYPE_SAME_CITY) - && !deliveryTypeId.equals(StateCode.DELIVERY_TYPE_SELF_PICK_UP) - && !deliveryTypeId.equals(StateCode.DELIVERY_TYPE_IN_STORE_SERVICE); + // 普通配送是指除了同城配送、自提和到店服务之外的配送方式(没有物流轨迹的) + return !Objects.equals(deliveryTypeId, StateCode.DELIVERY_TYPE_SAME_CITY) + && !Objects.equals(deliveryTypeId, StateCode.DELIVERY_TYPE_SELF_PICK_UP) + && !Objects.equals(deliveryTypeId, StateCode.DELIVERY_TYPE_IN_STORE_SERVICE); + } + + /** + * 获取配送方式名称 + * + * @param deliveryTypeId 配送方式ID + * @return 配送方式名称 + */ + public static String getDeliveryExpressName(Integer deliveryTypeId) { + if (deliveryTypeId == null) return "其他配送"; + String name = StateCode.DELIVERY_TYPE_MAP.get(deliveryTypeId); + return name != null ? name : "其他配送"; + } + + /** + * 判断配送方式是否为同城配送 + * + * @param deliveryTypeId 配送方式ID + * @return 是否为普通配送 + */ + public static boolean isSameCityExpress(Integer deliveryTypeId) { + // 当配送方式ID为空时,返回false + if (deliveryTypeId == null) { + return false; + } + + return Objects.equals(deliveryTypeId, StateCode.DELIVERY_TYPE_SAME_CITY); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 547dcf72..ade67100 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -119,7 +119,7 @@ public class LakalaController extends BaseControllerImpl { return lakalaPayService.getBankCardBin(paramsJSON.getStr("bankCardNo")); } - @ApiOperation(value = "发货类交易确认收货通知", notes = "发货类交易确认收货通知 https://o.lakala.com/#/home/document/detail?id=1003") + @ApiOperation(value = "接收拉卡拉发货类交易确认收货通知", notes = "接收拉卡拉发货类交易确认收货通知 https://o.lakala.com/#/home/document/detail?id=1003") @RequestMapping(value = "/trans/receive/completeNotify", method = RequestMethod.POST) public ResponseEntity receiveCompleteNotify(HttpServletRequest request) { // 完整地址: https://mall.gpxscs.cn/api/mobile/shop/lakala/trans/receive/completeNotify diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java index e4c8e546..bafd6aef 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java @@ -823,6 +823,14 @@ public class LakalaApiServiceImpl implements LakalaApiService { Pair checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); if (!checkResult.getFirst()) { log.warn("[确认收货通知] 验签失败: {}", checkResult.getSecond()); + + try { + // 不管成功与否,写入确认收货通知日志,后续补偿遗漏分账的材料 + lklReceiveNotifyLogService.addOrUpdate(LakalaUtil.getBody(request)); + } catch (Exception e) { + log.error("[确认收货通知] 写入确认收货通知日志失败", e); + } + return JSONUtil.createObj().set("code", "FAIL").set("message", checkResult.getSecond()); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderLogisticsServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderLogisticsServiceImpl.java index 927670af..8c85cad9 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderLogisticsServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderLogisticsServiceImpl.java @@ -268,7 +268,9 @@ public class ShopOrderLogisticsServiceImpl extends BaseServiceImpl - + - AND oi.delivery_type_id IN (1,2,3,4,10) + AND oi.delivery_type_id IN (1,2,3,4,5,10,15) diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml index e296a517..2386122d 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml @@ -104,7 +104,8 @@ - + + @@ -143,7 +144,7 @@ soi.order_title, soi.delivery_type_id, soi.payment_type_id, soi.payment_time, LPAD(soi.order_pickup_num, 7, '0') as order_pickup_num_str, CASE WHEN soi.booking_state = 2 THEN 2 ELSE 1 END AS booking_state, soi.booking_begin_time, - sod.order_message, sod.order_shipping_fee, sod.order_shipping_fee_amount, sod.delivery_time, + sod.order_message, sod.order_shipping_fee, sod.order_shipping_fee_amount, sod.delivery_time, sod.delivery_type_id, (sod.order_discount_amount + sod.voucher_price + sod.order_points_fee + sod.order_adjust_fee) as total_discount_amount, sod.packing_fee, ssi.store_tel, From fc177025a038aed5a7d2af6dc4c2461047a07768 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Wed, 3 Dec 2025 18:39:58 +0800 Subject: [PATCH 70/81] =?UTF-8?q?=E8=A3=85=E4=BF=AE=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/static/diy/js/diy.js | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/mall-shop/src/main/resources/static/diy/js/diy.js b/mall-shop/src/main/resources/static/diy/js/diy.js index 74a302ee..870f1695 100644 --- a/mall-shop/src/main/resources/static/diy/js/diy.js +++ b/mall-shop/src/main/resources/static/diy/js/diy.js @@ -18107,14 +18107,28 @@ for (var t = 0; t < l[_x41903[4579]][_x41903[33]]; t++) l[_x41903[4579]][t][_x41903[4453]] == $(e[_x41903[476]])[_x41903[217]](_x41903[4547]) && (l[_x41903[820]] = JSON[_x41903[367]](l[_x41903[4579]][t][_x41903[4580]])); }, uploadImage: function(n) { - var o = $(n[_x41903[476]])[_x41903[217]](_x41903[4581]) || 0, r = $(n[_x41903[476]])[_x41903[217]](_x41903[4582]) || 0, s = $(n[_x41903[476]])[_x41903[217]](_x41903[4583]) || 0, a = $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) || 0, e = $(n[_x41903[476]])[_x41903[217]](_x41903[4585]) || 0; - $(n[_x41903[476]])[_x41903[217]](_x41903[4522]); + console.log(JSON.stringify(n)) + const $input = $(n.target) + var o = $input.attr('imgwidth') || 0,//4581 + r = $input.attr('imgheight') || 0,//4582 + s = $input.attr('imgSize') || 0,//4583 + a = $input.attr('fileId') || 0,//4584 + e = $input.attr('uptype') || 0;//4585 + var msType= $input.attr('msType');//msType4522 + // $(n[_x41903[476]])[_x41903[217]](_x41903[4522]);//msType4522 if (1 == e) { - if ($(n[_x41903[476]])[_x41903[217]](_x41903[4583])) return void $[_x41903[39]](l[_x41903[4490]], function(e, t) { - t[_x41903[4453]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { - 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])), - t[_x41903[4589]] = e[_x41903[473]][_x41903[688]], - c(); + // if (s) return void $[_x41903[39]](l[_x41903[4490]], function(e, t) { + // t[_x41903[4453]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { + // 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])), + // t[_x41903[4589]] = e[_x41903[473]][_x41903[688]], + // c(); + // }, $(n[_x41903[476]])[_x41903[217]](_x41903[4583])); + // }); + if (s) return void l.pageList.forEach((e,t)=>{ + t[_x41903[4453]] == a && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { + 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])), + t[_x41903[4589]] = e[_x41903[473]][_x41903[688]], + c(); }, $(n[_x41903[476]])[_x41903[217]](_x41903[4583])); }); } else if (2 != e) if (3 == e) try { @@ -18181,14 +18195,14 @@ 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4597])), i[_x41903[4488]][_x41903[473]][_x41903[2345]] = e[_x41903[473]][_x41903[688]], c(); - }, 500); + }, 10240); } } else 3 == i[_x41903[4420]] ? $[_x41903[39]](i[_x41903[4598]][_x41903[473]], function(e, t) { t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4599])), t[_x41903[2345]] = e[_x41903[473]][_x41903[688]], c(); - }, 800); + }, 10240); }) : 4 == i[_x41903[4420]] ? $[_x41903[39]](i[_x41903[4600]][_x41903[473]], function(e, t) { if (t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584])) { switch (parseInt(i[_x41903[4600]][_x41903[4601]])) { @@ -18211,24 +18225,24 @@ 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4602])), t[_x41903[2345]] = e[_x41903[473]][_x41903[688]], c(); - }, 200); + }, 10240); } }) : 6 == i[_x41903[4420]] ? $[_x41903[39]](i[_x41903[4603]][_x41903[473]], function(e, t) { t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4604])), t[_x41903[2345]] = e[_x41903[473]][_x41903[688]], c(); - }, 800), _x41903[4605] + t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { + }, 10240), _x41903[4605] + t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4606])), t[_x41903[4607]] = e[_x41903[473]][_x41903[688]], c(); - }, 800); + }, 10240); }) : 7 == i[_x41903[4420]] ? $[_x41903[39]](i[_x41903[4608]][_x41903[473]], function(e, t) { t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4609])), t[_x41903[2345]] = e[_x41903[473]][_x41903[688]], c(); - }, 200); + }, 10240); }) : 12 == i[_x41903[4420]] && i[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) ? publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4610])), i[_x41903[4612]][_x41903[4611]] = e[_x41903[473]][_x41903[688]], @@ -18263,16 +18277,16 @@ 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4619])), t[_x41903[4555]] = e[_x41903[473]][_x41903[688]], c(); - }, 40) : e + 12 == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { + }, 10240) : e + 12 == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4620])), t[_x41903[4556]] = e[_x41903[473]][_x41903[688]], c(); - }, 40); + }, 10240); }), _x41903[4621] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[4584]), function(e) { 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4622])), l[_x41903[4458]][_x41903[4623]][_x41903[2345]] = e[_x41903[473]][_x41903[688]], c(); - }, 800); + }, 10240); }, selectTabBar: function(e) { l[_x41903[4573]] = $(e[_x41903[476]])[_x41903[217]](_x41903[4573]) || 0; @@ -18786,8 +18800,11 @@ }, uploadImage: function(e, t, i) { var n; - $(_x41903[130] + e)[0][_x41903[4708]][0][_x41903[1279]] / 1024 <= i ? (n = _x41903[4] != typeof authorization ? tpl_image_upload_url + _x41903[4709] + encodeURIComponent(authorization) : tpl_image_upload_url, - $[_x41903[4710]]({ + console.log($("#" + e)[0].files) + console.log($("#" + e)[0].files[0].size / 1024) + $("#" + e)[0].files[0].size / 1024 <= i ? (n = _x41903[4] != typeof authorization ? tpl_image_upload_url + _x41903[4709] + encodeURIComponent(authorization) : tpl_image_upload_url, + + $.ajaxFileUpload({ url: n, secureuri: !1, fileElementId: e, @@ -18796,7 +18813,8 @@ error: function(e, t, i) { console[_x41903[820]](e, t, i); } - })) : $[_x41903[2030]][_x41903[4089]](__(_x41903[4711]) + i + _x41903[4712]); + })) : $.dialog.alert("最大支持上传" + i + "kb"); + }, paging: function(e, t, i) { 0 < t[_x41903[1201]][_x41903[33]] && (e[_x41903[4531]] = i, e[_x41903[4713]] = t[_x41903[4714]], From 9051b0702d4e34c516225fd42df8de709e8730d6 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 4 Dec 2025 10:28:47 +0800 Subject: [PATCH 71/81] =?UTF-8?q?=E8=A3=85=E4=BF=AE=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mall-shop/src/main/resources/static/diy/js/diy.js | 2 +- mall-shop/src/main/resources/templates/diy.html | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mall-shop/src/main/resources/static/diy/js/diy.js b/mall-shop/src/main/resources/static/diy/js/diy.js index 870f1695..244772b6 100644 --- a/mall-shop/src/main/resources/static/diy/js/diy.js +++ b/mall-shop/src/main/resources/static/diy/js/diy.js @@ -18129,7 +18129,7 @@ 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])), t[_x41903[4589]] = e[_x41903[473]][_x41903[688]], c(); - }, $(n[_x41903[476]])[_x41903[217]](_x41903[4583])); + }, s); }); } else if (2 != e) if (3 == e) try { $[_x41903[39]](l[_x41903[820]], function(e, t) { diff --git a/mall-shop/src/main/resources/templates/diy.html b/mall-shop/src/main/resources/templates/diy.html index ba2362b5..2f71999a 100644 --- a/mall-shop/src/main/resources/templates/diy.html +++ b/mall-shop/src/main/resources/templates/diy.html @@ -354,7 +354,7 @@ + :imgSize="10240" :uptype="1"/> @@ -2854,12 +2854,12 @@ + :imgheight="200" :imgSize="1024"/> + :imgheight="200" :imgSize="1024"/> @@ -3408,11 +3408,11 @@ v-on:change="uploadImage" :fileId="item.id" :uptype="4" :msType="14" :imgwidth="100" :imgheight="100" - :imgSize="40"/> + :imgSize="10240"/> + :imgheight="100" :imgSize="10240"/>

@@ -3487,10 +3487,10 @@ v-on:change="uploadImage" :fileId="item.id" :uptype="5" :msType="15" :imgwidth="100" :imgheight="100" - :imgSize="40"/> + :imgSize="10240"/> + :imgheight="100" :imgSize="10240"/>
From 87f777ca78dd69f8e7ef4e63120201711a5dbcd2 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 4 Dec 2025 11:18:04 +0800 Subject: [PATCH 72/81] =?UTF-8?q?=E8=A3=85=E4=BF=AE=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/static/diy/js/diy.js | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/mall-shop/src/main/resources/static/diy/js/diy.js b/mall-shop/src/main/resources/static/diy/js/diy.js index 244772b6..0d826996 100644 --- a/mall-shop/src/main/resources/static/diy/js/diy.js +++ b/mall-shop/src/main/resources/static/diy/js/diy.js @@ -18124,13 +18124,23 @@ // c(); // }, $(n[_x41903[476]])[_x41903[217]](_x41903[4583])); // }); - if (s) return void l.pageList.forEach((e,t)=>{ - t[_x41903[4453]] == a && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { - 250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])), - t[_x41903[4589]] = e[_x41903[473]][_x41903[688]], - c(); - }, s); - }); + if (s) { + l.pageList.forEach((e,t)=>{ + console.log("e.Id---"+e.Id); + console.log("e.Id---"+t[_x41903[4453]]); + console.log(e.Id===a); + if(e.Id == a){ + publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { + if(250 == e[_x41903[686]]){ + $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])); + } + t[_x41903[4589]] = e[_x41903[473]][_x41903[688]]; + c(); + }, s); + } + }); + return; + } } else if (2 != e) if (3 == e) try { $[_x41903[39]](l[_x41903[820]], function(e, t) { t[_x41903[124]] == a && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { From 76b7832908da865d922b7a30aba35e4b7b49f5b4 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 4 Dec 2025 14:26:27 +0800 Subject: [PATCH 73/81] =?UTF-8?q?=E5=88=86=E4=BA=AB=E5=9B=BE=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D=EF=BC=8C=E7=BF=BB=E8=AF=91=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/static/diy/js/diy.js | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/mall-shop/src/main/resources/static/diy/js/diy.js b/mall-shop/src/main/resources/static/diy/js/diy.js index 0d826996..c439732b 100644 --- a/mall-shop/src/main/resources/static/diy/js/diy.js +++ b/mall-shop/src/main/resources/static/diy/js/diy.js @@ -18114,6 +18114,7 @@ s = $input.attr('imgSize') || 0,//4583 a = $input.attr('fileId') || 0,//4584 e = $input.attr('uptype') || 0;//4585 + var id=$input.attr('id'); var msType= $input.attr('msType');//msType4522 // $(n[_x41903[476]])[_x41903[217]](_x41903[4522]);//msType4522 if (1 == e) { @@ -18125,16 +18126,23 @@ // }, $(n[_x41903[476]])[_x41903[217]](_x41903[4583])); // }); if (s) { - l.pageList.forEach((e,t)=>{ - console.log("e.Id---"+e.Id); - console.log("e.Id---"+t[_x41903[4453]]); - console.log(e.Id===a); - if(e.Id == a){ - publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { - if(250 == e[_x41903[686]]){ - $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])); + l.pageList.forEach((el,t)=>{ + console.log("el.Id---"+el.Id); + console.log("el.Id---"+t[_x41903[4453]]); + if(el.Id == a){ + // publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) { + // if(250 == e.status){ + // $.dialog.alert("上传发生错误"); + // // $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4588])); + // } + // el.ShareImg = e.data.url; + // c(); + // }, s); + publicFun.uploadImage(id, function(e) { + if(250 == e.status){ + $.dialog.alert("上传发生错误"); } - t[_x41903[4589]] = e[_x41903[473]][_x41903[688]]; + el.ShareImg = e.data.url; c(); }, s); } From ca48e78dd1ad5847d132b6b9bd765f8293c71989 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Thu, 4 Dec 2025 15:25:56 +0800 Subject: [PATCH 74/81] =?UTF-8?q?es=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=EF=BC=8C=E7=A1=AE=E8=AE=A4=E6=94=B6=E8=B4=A7?= =?UTF-8?q?=E5=90=8E=E5=8A=A0=E5=85=A5=E5=8E=BB=E9=99=A4=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/suisung/mall/common/utils/JiebaUtils.java | 2 +- .../mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/JiebaUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/JiebaUtils.java index ce321e70..4a10428e 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/JiebaUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/JiebaUtils.java @@ -286,7 +286,7 @@ public class JiebaUtils { //JiebaSegmenter segmenter = new JiebaSegmenter(); loadUserDict(); String protectedText = protectPatterns(text); - log.info("protectedText: {}", protectedText); + log.debug("protectedText: {}", protectedText); List tokens = segmenter.process(protectedText,JiebaSegmenter.SegMode.SEARCH).stream() .map(token -> token.word) //.filter(word -> word.length() > 1) // 过滤单字 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java index b0b770f7..2eeaa809 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java @@ -207,7 +207,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); // 已发货,已签收 queryWrapper.in("order_state_id", StateCode.ORDER_STATE_SHIPPED, StateCode.ORDER_STATE_RECEIVED); - + queryWrapper.eq("order_is_received",CommonConstant.Disable); // 默认7天,自动收货 // 配置了发货或已签收的订单,1天自动收货 Float order_autofinish_time = accountBaseConfigService.getConfig("order_autofinish_time", 7f); From 48da403179238b2550168b9a38dd8eac2e89ab01 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Fri, 5 Dec 2025 11:03:20 +0800 Subject: [PATCH 75/81] =?UTF-8?q?es=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=EF=BC=8C=E7=A1=AE=E8=AE=A4=E6=94=B6=E8=B4=A7?= =?UTF-8?q?=E5=90=8E=E5=8A=A0=E5=85=A5=E5=8E=BB=E9=99=A4=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/AdminBaseMenuController.java | 34 +++++ .../admin/AdminBaseProtocolController.java | 58 +++++--- .../admin/AdminRightsBaseController.java | 48 ++++++- .../admin/service/AdminBaseMenuService.java | 3 + .../service/AdminBaseProtocolService.java | 14 ++ .../admin/service/AdminRightsBaseService.java | 6 + .../impl/AdminBaseMenuServiceImpl.java | 60 +++++++++ .../impl/AdminBaseProtocolServiceImpl.java | 125 +++++++++++++++++- .../impl/AdminRightsBaseServiceImpl.java | 58 ++++++++ .../mall/common/feignService/ShopService.java | 7 +- .../common/modules/admin/AdminBaseMenu.java | 6 +- .../modules/admin/AdminBaseProtocol.java | 8 ++ .../common/modules/admin/AdminRightsBase.java | 6 +- .../store/ShopStoreEmployeeRightsBase.java | 6 +- ...ShopStoreEmployeeRightsBaseController.java | 86 ++++++++++-- .../ShopStoreEmployeeRightsBaseService.java | 9 ++ ...hopStoreEmployeeRightsBaseServiceImpl.java | 68 ++++++++++ sql/shop/dev/20251201_ddl.sql | 5 + 18 files changed, 560 insertions(+), 47 deletions(-) create mode 100644 sql/shop/dev/20251201_ddl.sql diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseMenuController.java b/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseMenuController.java index f91b1ce2..a077e8eb 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseMenuController.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseMenuController.java @@ -1,13 +1,19 @@ package com.suisung.mall.admin.controller.admin; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.admin.service.AdminBaseMenuService; import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.admin.AdminBaseMenu; import com.suisung.mall.common.modules.admin.Router; +import com.suisung.mall.common.utils.ContextUtil; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.util.Arrays; import java.util.List; /** @@ -38,6 +44,18 @@ public class AdminBaseMenuController { return CommonResult.success(routers); } + /** + * 获取用户权限目录信息 + * + * @param + * @return + */ + @RequestMapping(value = "/treePage", method = RequestMethod.GET) + public IPage getRouterList(AdminBaseMenu adminBaseMenu, @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { + return adminBaseMenuService.treePage(adminBaseMenu,pageNum,pageSize); + } + /** * 获取所有菜单配置 * @@ -83,6 +101,22 @@ public class AdminBaseMenuController { return adminBaseMenuService.updateAdminBaseMenu(adminBaseMenu); } + /** + * 批量删除 + * + * @param menu_ids + * @return + */ + @ApiOperation(value = "权限表 -批量删除", notes = "权限表 -批量删除") + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) + public CommonResult deleteBatch(String menu_ids) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + boolean flag = adminBaseMenuService.remove(Arrays.asList(menu_ids.split(","))); + return CommonResult.success(flag); + } } diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseProtocolController.java b/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseProtocolController.java index 97cb165b..c300a57d 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseProtocolController.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminBaseProtocolController.java @@ -1,17 +1,16 @@ package com.suisung.mall.admin.controller.admin; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; + import com.suisung.mall.admin.service.AdminBaseProtocolService; import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.admin.AdminBaseProtocol; +import com.suisung.mall.common.utils.ContextUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.Arrays; import java.util.List; @@ -43,15 +42,11 @@ public class AdminBaseProtocolController { */ @ApiOperation(value = "基础通信协议表-分页列表查询", notes = "基础通信协议表-分页列表查询") @RequestMapping(value = "/list", method = RequestMethod.GET) - public CommonResult list(@RequestParam(name = "queryWrapper", required = false) AdminBaseProtocol adminBaseProtocol, + public CommonResult list(AdminBaseProtocol adminBaseProtocol, @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.orderByAsc("cmd_id"); - - IPage pageList = adminBaseProtocolService.lists(queryWrapper, pageNum, pageSize); - return CommonResult.success(pageList); + return CommonResult.success(adminBaseProtocolService.getPageAdminBaseProtocol(adminBaseProtocol, pageNum, pageSize)); } /** @@ -61,9 +56,13 @@ public class AdminBaseProtocolController { * @return */ @ApiOperation(value = "基础通信协议表-编辑", notes = "基础通信协议表-编辑") - @RequestMapping(value = "/edit", method = RequestMethod.POST) - public CommonResult edit(AdminBaseProtocol adminBaseProtocol) { - boolean flag = adminBaseProtocolService.edit(adminBaseProtocol); + @RequestMapping(value = "/edit", method = RequestMethod.PUT) + public CommonResult edit(@RequestBody AdminBaseProtocol adminBaseProtocol) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + boolean flag = adminBaseProtocolService.editAdminBaseProtocol(adminBaseProtocol); return CommonResult.success(flag); } @@ -87,9 +86,13 @@ public class AdminBaseProtocolController { * @return */ @ApiOperation(value = "基础通信协议表-批量删除", notes = "基础通信协议表-批量删除") - @RequestMapping(value = "/deleteBatch", method = RequestMethod.POST) + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public CommonResult deleteBatch(@RequestParam(name = "cmd_ids") String cmd_ids) { - boolean flag = adminBaseProtocolService.removeByIds(Arrays.asList(cmd_ids.split(","))); + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + boolean flag = adminBaseProtocolService.deleteBatchByIds(Arrays.asList(cmd_ids.split(","))); return CommonResult.success(flag); } @@ -111,10 +114,25 @@ public class AdminBaseProtocolController { * @return */ @ApiOperation(value = "基础通信协议表-新增", notes = "基础通信协议表-新增") - @RequestMapping(value = "/add", method = RequestMethod.PUT) - public CommonResult add(AdminBaseProtocol adminBaseProtocol) { - boolean flag = adminBaseProtocolService.save(adminBaseProtocol); + @RequestMapping(value = "/add", method = RequestMethod.POST) + public CommonResult add(@RequestBody AdminBaseProtocol adminBaseProtocol) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + boolean flag = adminBaseProtocolService.addAdminBaseProtocol(adminBaseProtocol); return CommonResult.success(flag); } + + /** + * 根据id查出路由,主要是显示平台权限名称和店铺权限名称 + * @param cmd_id + * @return + */ + @ApiOperation(value = "基础通信协议表-查找单个协议", notes = "基础通信协议表-查找单个协议") + @RequestMapping(value = "/getOneById", method = RequestMethod.GET) + public CommonResult getOneById(@RequestParam(name = "cmd_id") Integer cmd_id) { + return CommonResult.success(adminBaseProtocolService.getOneByCmId(cmd_id)); + } } diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminRightsBaseController.java b/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminRightsBaseController.java index 180e3fba..9ff7d789 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminRightsBaseController.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/controller/admin/AdminRightsBaseController.java @@ -1,11 +1,15 @@ package com.suisung.mall.admin.controller.admin; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.admin.service.AdminRightsBaseService; import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.admin.AdminRightsBase; import com.suisung.mall.common.modules.admin.ElTree; +import com.suisung.mall.common.utils.ContextUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -40,7 +44,7 @@ public class AdminRightsBaseController { */ @ApiOperation(value = "权限表 -分页列表查询", notes = "权限表 -分页列表查询") @RequestMapping(value = "/list", method = RequestMethod.GET) - public CommonResult list(@RequestParam(name = "queryWrapper", required = false) AdminRightsBase adminRightsBase, + public CommonResult list(AdminRightsBase adminRightsBase, @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { @@ -51,6 +55,21 @@ public class AdminRightsBaseController { return CommonResult.success(pageList); } + /** + * 树形分页列表查询 + * @param adminRightsBase + * @param pageNum + * @param pageSize + * @return + */ + @ApiOperation(value = "权限表 -树形分页列表查询", notes = "权限表 -树形分页列表查询") + @RequestMapping(value = "/treeList", method = RequestMethod.GET) + public IPage treeList(AdminRightsBase adminRightsBase, + @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { + return adminRightsBaseService.treePage(adminRightsBase, pageNum, pageSize); + } + /** * 获取tree数据 @@ -78,8 +97,12 @@ public class AdminRightsBaseController { * @return */ @ApiOperation(value = "权限表 -编辑", notes = "权限表 -编辑") - @RequestMapping(value = "/edit", method = RequestMethod.POST) - public CommonResult edit(AdminRightsBase adminRightsBase) { + @RequestMapping(value = "/edit", method = RequestMethod.PUT) + public CommonResult edit(@RequestBody AdminRightsBase adminRightsBase) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } boolean flag = adminRightsBaseService.edit(adminRightsBase); return CommonResult.success(flag); } @@ -94,6 +117,10 @@ public class AdminRightsBaseController { @ApiOperation(value = "权限表 -通过rights_id删除", notes = "权限表 -通过rights_id删除") @RequestMapping(value = "/delete", method = RequestMethod.POST) public CommonResult delete(@RequestParam(name = "rights_id") String rights_id) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } boolean flag = adminRightsBaseService.remove(rights_id); return CommonResult.success(flag); } @@ -105,8 +132,12 @@ public class AdminRightsBaseController { * @return */ @ApiOperation(value = "权限表 -批量删除", notes = "权限表 -批量删除") - @RequestMapping(value = "/deleteBatch", method = RequestMethod.POST) - public CommonResult deleteBatch(@RequestParam(name = "rights_ids") String rights_ids) { + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) + public CommonResult deleteBatch(String rights_ids) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } boolean flag = this.adminRightsBaseService.remove(Arrays.asList(rights_ids.split(","))); return CommonResult.success(flag); } @@ -120,6 +151,13 @@ public class AdminRightsBaseController { @ApiOperation(value = "权限表 -新增", notes = "权限表 -编辑") @RequestMapping(value = "/add", method = RequestMethod.POST) public CommonResult add(@RequestBody AdminRightsBase adminRightsBase) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + if(ObjectUtil.isEmpty(adminRightsBase.getRights_parent_id())){ + adminRightsBase.setRights_parent_id(0); + } boolean flag = adminRightsBaseService.save(adminRightsBase); return CommonResult.success(flag); } diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseMenuService.java b/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseMenuService.java index 435a480a..a9002b88 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseMenuService.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseMenuService.java @@ -1,6 +1,7 @@ package com.suisung.mall.admin.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.admin.AdminBaseMenu; import com.suisung.mall.common.modules.admin.Router; @@ -32,4 +33,6 @@ public interface AdminBaseMenuService extends IBaseService { CommonResult saveAdminBaseMenu(AdminBaseMenu adminBaseMenu); CommonResult updateAdminBaseMenu(AdminBaseMenu adminBaseMenu); + + IPage treePage(AdminBaseMenu adminBaseMenu, Integer pageNum, Integer pageSize); } diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseProtocolService.java b/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseProtocolService.java index d3ba53e4..dc208325 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseProtocolService.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminBaseProtocolService.java @@ -1,6 +1,7 @@ package com.suisung.mall.admin.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.common.modules.admin.AdminBaseProtocol; import com.suisung.mall.core.web.service.IBaseService; @@ -21,4 +22,17 @@ public interface AdminBaseProtocolService extends IBaseService> initResourceRolesMap(); + + /** + * 分页查询路由 + */ + IPage getPageAdminBaseProtocol(AdminBaseProtocol adminBaseProtocol,Integer pageNum,Integer pageSize); + + boolean addAdminBaseProtocol(AdminBaseProtocol adminBaseProtocol); + + boolean editAdminBaseProtocol(AdminBaseProtocol adminBaseProtocol); + + boolean deleteBatchByIds(List adminBaseProtocolIds); + + AdminBaseProtocol getOneByCmId(Integer cmId); } diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminRightsBaseService.java b/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminRightsBaseService.java index 68544b26..5dd916dd 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminRightsBaseService.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/service/AdminRightsBaseService.java @@ -1,6 +1,7 @@ package com.suisung.mall.admin.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.common.modules.admin.AdminRightsBase; import com.suisung.mall.common.modules.admin.ElTree; import com.suisung.mall.core.web.service.IBaseService; @@ -21,4 +22,9 @@ public interface AdminRightsBaseService extends IBaseService { * 获取tree数据 */ List tree(); + + /** + * 获取tree数据 + */ + IPage treePage(AdminRightsBase adminRightsBase, Integer pageNum, Integer pageSize); } diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseMenuServiceImpl.java b/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseMenuServiceImpl.java index 70e702e0..e63c9b4b 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseMenuServiceImpl.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseMenuServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.suisung.mall.admin.mapper.AdminBaseMenuMapper; import com.suisung.mall.admin.service.AccountBaseConfigService; @@ -870,6 +871,16 @@ public class AdminBaseMenuServiceImpl extends BaseServiceImpl treePage(AdminBaseMenu adminBaseMenu, Integer pageNum, Integer pageSize) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("没有权限"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("menu_id"); + if(adminBaseMenu!=null){ + if(StringUtils.isNotEmpty(adminBaseMenu.getMenu_name())){ + queryWrapper.like("menu_name", adminBaseMenu.getMenu_name()); + } + } + queryWrapper.eq("menu_parent_id",0); + IPage pageList = this.lists(queryWrapper, pageNum, pageSize); + List adminBaseMenus= pageList.getRecords(); + adminBaseMenus=buildAdminBaseMenuTree(adminBaseMenus,0); + pageList.setRecords(adminBaseMenus); + return pageList; + } + /** + * 递归构建tree + * + * @param bases + * @param pid + * @return + */ + public List buildAdminBaseMenuTree(List bases, Integer pid) { + List tree = new ArrayList<>(); + bases.forEach(s -> { + if (s.getMenu_parent_id().intValue() == pid.intValue()) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("menu_parent_id", s.getMenu_id()); + long countAdminRightsBase=this.count(queryWrapper); + if(countAdminRightsBase>0){ + s.setChildren(buildAdminBaseMenuTree(this.list(queryWrapper), s.getMenu_id())); + } + tree.add(s); + } + }); + return tree; + } /** * 校验是否为平台 diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseProtocolServiceImpl.java b/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseProtocolServiceImpl.java index 87d59469..fde4fd8f 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseProtocolServiceImpl.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminBaseProtocolServiceImpl.java @@ -3,18 +3,30 @@ package com.suisung.mall.admin.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.admin.mapper.AdminBaseProtocolMapper; +import com.suisung.mall.admin.service.AdminBaseMenuService; import com.suisung.mall.admin.service.AdminBaseProtocolService; +import com.suisung.mall.admin.service.AdminRightsBaseService; import com.suisung.mall.admin.service.AdminRightsGroupService; import com.suisung.mall.common.constant.AuthConstant; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; +import com.suisung.mall.common.feignService.ShopService; +import com.suisung.mall.common.modules.admin.AdminBaseMenu; import com.suisung.mall.common.modules.admin.AdminBaseProtocol; +import com.suisung.mall.common.modules.admin.AdminRightsBase; import com.suisung.mall.common.modules.admin.AdminRightsGroup; +import com.suisung.mall.common.modules.store.ShopStoreEmployeeRightsBase; +import com.suisung.mall.common.utils.ContextUtil; import com.suisung.mall.core.web.service.RedisService; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; +import org.hibernate.validator.internal.util.stereotypes.Lazy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.io.Serializable; import java.util.*; @@ -38,6 +50,17 @@ public class AdminBaseProtocolServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("ctl",adminBaseProtocol.getCtl()); + queryWrapper.eq("met",adminBaseProtocol.getMet()); + queryWrapper.eq("mdu",adminBaseProtocol.getMdu()); + List adminBaseProtocolList=this.list(queryWrapper); + if(!adminBaseProtocolList.isEmpty()){ + throw new ApiException("已存在相同的路由"); + } boolean flag = save(adminBaseProtocol); initResourceRolesMap(); return flag; @@ -58,25 +89,83 @@ public class AdminBaseProtocolServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("ctl",adminBaseProtocol.getCtl()); + queryWrapper.eq("met",adminBaseProtocol.getMet()); + queryWrapper.eq("mdu",adminBaseProtocol.getMdu()); + List adminBaseProtocolList=this.list(queryWrapper); + if(!adminBaseProtocolList.isEmpty()){ + throw new ApiException("已存在相同的路由"); + } boolean flag = updateById(adminBaseProtocol); initResourceRolesMap(); return flag; } /** - * 根据cmd_id删除 - * - * @param cmd_id + * 根据cmd_id批量删除 + * @param adminBaseProtocolIds * @return */ @Override - public boolean remove(Serializable cmd_id) { - boolean flag = super.remove(cmd_id); + @Transactional(rollbackFor = Exception.class) + public boolean deleteBatchByIds(List adminBaseProtocolIds) { + boolean flag = removeBatchByIds(adminBaseProtocolIds); initResourceRolesMap(); return flag; } + @Override + public AdminBaseProtocol getOneByCmId(Integer cmId) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("cmd_id",cmId); + List adminBaseProtocolList=this.list(queryWrapper); + if(adminBaseProtocolList.isEmpty()){ + throw new ApiException("不存在通信协议"); + } + AdminBaseProtocol adminBaseProtocol=adminBaseProtocolList.get(0); + String rigthsIds= adminBaseProtocol.getRights_id(); + if(StringUtils.isNotBlank(rigthsIds)){ + QueryWrapper adminBaseMenuQuery = new QueryWrapper<>(); + adminBaseMenuQuery.eq("menu_url_path",adminBaseProtocol.getPath()); + List adminBaseMenuList= adminBaseMenuService.list(adminBaseMenuQuery); + if(adminBaseMenuList.isEmpty()){ + throw new ApiException("需要配置菜单"); + } + List rightsIdList= Arrays.asList(rigthsIds.split(",")); + List rightsIdsIntList=new ArrayList<>(); + rightsIdList.forEach(s->rightsIdsIntList.add(Integer.parseInt(s))); + QueryWrapper adminRightsBaseQuery = new QueryWrapper<>(); + adminRightsBaseQuery.in("rights_id",rightsIdsIntList); + List adminRightsBaseList= adminRightsBaseService.list(adminRightsBaseQuery); + AdminBaseMenu adminBaseMenu=adminBaseMenuList.get(0); + if(!adminRightsBaseList.isEmpty()){ + adminRightsBaseList= adminRightsBaseList.stream().filter(s->s.getRights_name().equals(adminBaseMenu.getMenu_name())).collect(Collectors.toList()); + Map adminRightBaseMap=adminRightsBaseList.stream().collect( + Collectors.toMap(AdminRightsBase::getRights_id, + AdminRightsBase::getRights_name)); + adminBaseProtocol.setAdminRightBaseMap(adminRightBaseMap); + } + QueryWrapper shopStoreEmployeeRightsBasesQuery = new QueryWrapper<>(); + shopStoreEmployeeRightsBasesQuery.in("rights_id",rightsIdsIntList); + List shopStoreEmployeeRightsBases= shopService.queryByRightsIds(rigthsIds); + if(!shopStoreEmployeeRightsBases.isEmpty()){ + shopStoreEmployeeRightsBases= shopStoreEmployeeRightsBases.stream().filter(s->s.getRights_name().equals(adminBaseMenu.getMenu_name())).collect(Collectors.toList()); + Map shopStoreEmployeeRightsBaseMap=shopStoreEmployeeRightsBases.stream().collect( + Collectors.toMap(ShopStoreEmployeeRightsBase::getRights_id, + ShopStoreEmployeeRightsBase::getRights_name)); + adminBaseProtocol.setShopStoreEmployeeRightsBaseMap(shopStoreEmployeeRightsBaseMap); + } + + } + return adminBaseProtocol; + } + @Override public Map> initResourceRolesMap() { // 资源-分组信息 @@ -108,6 +197,28 @@ public class AdminBaseProtocolServiceImpl extends BaseServiceImpl getPageAdminBaseProtocol(AdminBaseProtocol adminBaseProtocol, Integer pageNum, Integer pageSize) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc("cmd_id"); + if(adminBaseProtocol!=null){ + if(StringUtils.isNotBlank(adminBaseProtocol.getComment())){ + queryWrapper.like("comment", adminBaseProtocol.getComment()); + } + if(StringUtils.isNotBlank(adminBaseProtocol.getCtl())){ + queryWrapper.like("ctl", adminBaseProtocol.getCtl()); + } + } + return this.lists(queryWrapper, pageNum, pageSize); + } + + + + /** * 对比两个数组是否有相同元素 * diff --git a/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminRightsBaseServiceImpl.java b/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminRightsBaseServiceImpl.java index 0b65b477..4c10e820 100644 --- a/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminRightsBaseServiceImpl.java +++ b/mall-admin/src/main/java/com/suisung/mall/admin/service/impl/AdminRightsBaseServiceImpl.java @@ -2,11 +2,16 @@ package com.suisung.mall.admin.service.impl; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.admin.mapper.AdminRightsBaseMapper; import com.suisung.mall.admin.service.AccountBaseConfigService; import com.suisung.mall.admin.service.AdminRightsBaseService; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.admin.AdminRightsBase; import com.suisung.mall.common.modules.admin.ElTree; +import com.suisung.mall.common.utils.ContextUtil; +import com.suisung.mall.common.utils.StringUtils; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -48,6 +53,59 @@ public class AdminRightsBaseServiceImpl extends BaseServiceImpl treePage(AdminRightsBase adminRightsBase, Integer pageNum, Integer pageSize) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("没有权限"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc("rights_id"); + if(adminRightsBase!=null){ + if(StringUtils.isNotEmpty(adminRightsBase.getRights_name())){ + queryWrapper.like("rights_name", adminRightsBase.getRights_name()); + } + } + queryWrapper.eq("rights_parent_id",0); + IPage pageList = this.lists(queryWrapper, pageNum, pageSize); + List adminRightsBases= pageList.getRecords(); + adminRightsBases=buildAdminRightBaseTree(adminRightsBases,0); + pageList.setRecords(adminRightsBases); + return pageList; + } + + /** + * 递归构建tree + * + * @param bases + * @param pid + * @return + */ + public List buildAdminRightBaseTree(List bases, Integer pid) { + List tree = new ArrayList<>(); + bases.forEach(s -> { + if (s.getRights_parent_id().intValue() == pid.intValue()) { + AdminRightsBase adminRightsBase=new AdminRightsBase(); + adminRightsBase.setRights_id(s.getRights_id()); + adminRightsBase.setRights_name(s.getRights_name()); + adminRightsBase.setRights_parent_id(s.getRights_parent_id()); + adminRightsBase.setRights_order(s.getRights_order()); + adminRightsBase.setRights_remark(s.getRights_remark()); + adminRightsBase.setMenu_func(s.getMenu_func()); + // adminRightsBase.setChildren(buildAdminRightBaseTree(bases, s.getRights_id())); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("rights_parent_id", s.getRights_id()); + long countAdminRightsBase=this.count(queryWrapper); + if(countAdminRightsBase>0){ + adminRightsBase.setChildren(buildAdminRightBaseTree(this.list(queryWrapper), s.getRights_id())); + } + tree.add(adminRightsBase); + } + }); + return tree; + } + + /** * 递归构建tree * diff --git a/mall-common/src/main/java/com/suisung/mall/common/feignService/ShopService.java b/mall-common/src/main/java/com/suisung/mall/common/feignService/ShopService.java index b6140c37..73af2839 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/feignService/ShopService.java +++ b/mall-common/src/main/java/com/suisung/mall/common/feignService/ShopService.java @@ -18,10 +18,7 @@ import com.suisung.mall.common.modules.pay.dto.ItemActivityInfoDTO; import com.suisung.mall.common.modules.plantform.ShopPlantformSubsiteUser; import com.suisung.mall.common.modules.product.ShopProductBase; import com.suisung.mall.common.modules.product.ShopProductIndex; -import com.suisung.mall.common.modules.store.ShopStoreBase; -import com.suisung.mall.common.modules.store.ShopStoreEmployee; -import com.suisung.mall.common.modules.store.ShopStoreEmployeeKefu; -import com.suisung.mall.common.modules.store.ShopStoreEmployeeRightsGroup; +import com.suisung.mall.common.modules.store.*; import io.swagger.annotations.ApiOperation; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; @@ -337,5 +334,7 @@ public interface ShopService { Integer storeShoppingFeeInner(@RequestParam(name = "store_id") Integer store_id); + @GetMapping(value = "/admin/shop/shop-store-employee-rights-base/queryByRightsIds") + List queryByRightsIds(@RequestParam(name = "rights_ids") String rights_ids); } diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseMenu.java b/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseMenu.java index 505edd99..13fcbbaf 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseMenu.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseMenu.java @@ -1,6 +1,7 @@ package com.suisung.mall.common.modules.admin; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -11,6 +12,7 @@ import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; +import java.util.List; /** *

@@ -105,5 +107,7 @@ public class AdminBaseMenu implements Serializable { @ApiModelProperty(value = "允许关闭(BOOL):0-禁止;1-允许") private Integer menu_close; - + @TableField(exist = false) + @ApiModelProperty(value = "节点子集") + private List children; } diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseProtocol.java b/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseProtocol.java index 36e2895f..5c916361 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseProtocol.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminBaseProtocol.java @@ -1,6 +1,7 @@ package com.suisung.mall.common.modules.admin; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -10,6 +11,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.Map; /** *

@@ -61,5 +63,11 @@ public class AdminBaseProtocol implements Serializable { @ApiModelProperty(value = "请求地址") private String path; + //平台权限id和名称 + @TableField(exist = false) + private Map adminRightBaseMap; + //店铺权限id和名称 + @TableField(exist = false) + private Map shopStoreEmployeeRightsBaseMap; } diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminRightsBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminRightsBase.java index c0acf6e6..3d250b54 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminRightsBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/admin/AdminRightsBase.java @@ -1,6 +1,7 @@ package com.suisung.mall.common.modules.admin; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -10,6 +11,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.List; /** *

@@ -47,5 +49,7 @@ public class AdminRightsBase implements Serializable { @ApiModelProperty(value = "功能开启:跟设置config_key") private String menu_func; - + @ApiModelProperty(value = "节点子集") + @TableField(exist = false) + private List children; } diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreEmployeeRightsBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreEmployeeRightsBase.java index c19158c1..b1cbdda7 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreEmployeeRightsBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreEmployeeRightsBase.java @@ -1,6 +1,7 @@ package com.suisung.mall.common.modules.store; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -10,6 +11,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.List; /** *

@@ -47,5 +49,7 @@ public class ShopStoreEmployeeRightsBase implements Serializable { @ApiModelProperty(value = "功能开启:跟设置config_key") private String menu_func; - + @ApiModelProperty(value = "节点子集") + @TableField(exist = false) + private List children; } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreEmployeeRightsBaseController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreEmployeeRightsBaseController.java index 0f31ba7b..9f0407b6 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreEmployeeRightsBaseController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreEmployeeRightsBaseController.java @@ -1,16 +1,21 @@ package com.suisung.mall.shop.store.controller.admin; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.store.ShopStoreEmployeeRightsBase; +import com.suisung.mall.common.utils.ContextUtil; import com.suisung.mall.shop.store.service.ShopStoreEmployeeRightsBaseService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** *

@@ -52,29 +57,94 @@ public class ShopStoreEmployeeRightsBaseController { return CommonResult.success(shopStoreEmployeeRightsBaseService.getRightsBaseTree()); } + + /** + * 分页列表查询 + * @param shopStoreEmployeeRightsBase + * @param pageNum + * @param pageSize + * @return + */ + @ApiOperation(value = "权限表 -分页列表查询", notes = "权限表 -分页列表查询") + @RequestMapping(value = "/treeList", method = RequestMethod.GET) + public IPage treeList(ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase, + @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { + return shopStoreEmployeeRightsBaseService.treePage(shopStoreEmployeeRightsBase, pageNum, pageSize); + } + + /** + * 编辑新增 + * @param shopStoreEmployeeRightsBase + * @return + */ + @ApiOperation(value = "权限表 -新增", notes = "权限表 -新增") + @RequestMapping(value = "/add", method = RequestMethod.POST) + public CommonResult add(@RequestBody ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase) { + return shopStoreEmployeeRightsBaseService.addShopStoreEmployeeRightsBase(shopStoreEmployeeRightsBase); + } + /** * 编辑更新 - * * @param shopStoreEmployeeRightsBase * @return */ @ApiOperation(value = "权限表 -编辑", notes = "权限表 -编辑") - @RequestMapping(value = "/edit", method = RequestMethod.POST) - public CommonResult edit(ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase) { + @RequestMapping(value = "/edit", method = RequestMethod.PUT) + public CommonResult edit(@RequestBody ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } return CommonResult.success(shopStoreEmployeeRightsBaseService.edit(shopStoreEmployeeRightsBase)); } /** * 通过rights_id删除 - * * @param rights_id * @return */ @ApiOperation(value = "权限表 -通过rights_id删除", notes = "权限表 -通过rights_id删除") @RequestMapping(value = "/delete", method = RequestMethod.POST) public CommonResult delete(@RequestParam(name = "rights_id") String rights_id) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } return CommonResult.success(shopStoreEmployeeRightsBaseService.remove(rights_id)); } + /** + * 批量删除 + * @param rights_ids + * @return + */ + @ApiOperation(value = "权限表 -批量删除", notes = "权限表 -批量删除") + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) + public CommonResult deleteBatch(String rights_ids) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + boolean flag = shopStoreEmployeeRightsBaseService.remove(Arrays.asList(rights_ids.split(","))); + return CommonResult.success(flag); + } + + /** + * 根据id查询列表 + * @param rights_ids + * @return + */ + @ApiOperation(value = "权限表 -根据id查询列表", notes = "权限表 -根据id查询列表") + @RequestMapping(value = "/queryByRightsIds", method = RequestMethod.GET) + public List queryByRightsIds(String rights_ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List rights_idListStr = Arrays.asList(rights_ids.split(",")); + List rights_idList=new ArrayList<>(); + rights_idListStr.forEach(r->rights_idList.add(Integer.parseInt(r))); + queryWrapper.in("rights_id",rights_idList); + return shopStoreEmployeeRightsBaseService.list(queryWrapper); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreEmployeeRightsBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreEmployeeRightsBaseService.java index 4c0cb2af..978ed4cf 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreEmployeeRightsBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreEmployeeRightsBaseService.java @@ -1,5 +1,7 @@ package com.suisung.mall.shop.store.service; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.store.ShopStoreEmployeeRightsBase; import com.suisung.mall.core.web.service.IBaseService; @@ -19,4 +21,11 @@ public interface ShopStoreEmployeeRightsBaseService extends IBaseService getRightsBaseTree(); + /** + * 获取tree数据 + */ + IPage treePage(ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase, Integer pageNum, Integer pageSize); + + CommonResult addShopStoreEmployeeRightsBase(ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase); + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeRightsBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeRightsBaseServiceImpl.java index ffd2bf7a..fb37e3dc 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeRightsBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeRightsBaseServiceImpl.java @@ -3,7 +3,12 @@ package com.suisung.mall.shop.store.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.store.ShopStoreEmployeeRightsBase; +import com.suisung.mall.common.utils.ContextUtil; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.base.service.AccountBaseConfigService; import com.suisung.mall.shop.store.mapper.ShopStoreEmployeeRightsBaseMapper; @@ -47,6 +52,67 @@ public class ShopStoreEmployeeRightsBaseServiceImpl extends BaseServiceImpl treePage(ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase, Integer pageNum, Integer pageSize) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc("rights_id"); + + if(shopStoreEmployeeRightsBase!=null){ + if(com.suisung.mall.common.utils.StringUtils.isNotEmpty(shopStoreEmployeeRightsBase.getRights_name())){ + queryWrapper.like("rights_name", shopStoreEmployeeRightsBase.getRights_name()); + } + } + queryWrapper.eq("rights_parent_id",8); + IPage shopStoreEmployeeRightsBaseIPage= this.lists(queryWrapper, pageNum, pageSize); + List shopStoreEmployeeRightsBases= shopStoreEmployeeRightsBaseIPage.getRecords(); + shopStoreEmployeeRightsBases=buildShopStoreEmployeeRightsBaseTree(shopStoreEmployeeRightsBases,8); + shopStoreEmployeeRightsBaseIPage.setRecords(shopStoreEmployeeRightsBases); + return shopStoreEmployeeRightsBaseIPage; + } + + @Override + public CommonResult addShopStoreEmployeeRightsBase(ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase) { + UserDto userDto= ContextUtil.getCurrentUser(); + if(userDto.getRole_id()!=9){ + throw new ApiException("权限不足"); + } + if(ObjectUtil.isEmpty(shopStoreEmployeeRightsBase.getRights_parent_id())){ + shopStoreEmployeeRightsBase.setRights_parent_id(8); + } + this.save(shopStoreEmployeeRightsBase); + return CommonResult.success(); + } + + /** + * 递归构建tree + * + * @param bases + * @param pid + * @return + */ + public List buildShopStoreEmployeeRightsBaseTree(List bases, Integer pid) { + List tree = new ArrayList<>(); + bases.forEach(s -> { + if (ObjectUtil.equal(s.getRights_parent_id(),pid)) { + ShopStoreEmployeeRightsBase shopStoreEmployeeRightsBase=new ShopStoreEmployeeRightsBase(); + shopStoreEmployeeRightsBase.setRights_id(s.getRights_id()); + shopStoreEmployeeRightsBase.setRights_name(s.getRights_name()); + shopStoreEmployeeRightsBase.setRights_parent_id(s.getRights_parent_id()); + shopStoreEmployeeRightsBase.setRights_order(s.getRights_order()); + shopStoreEmployeeRightsBase.setRights_remark(s.getRights_remark()); + shopStoreEmployeeRightsBase.setMenu_func(s.getMenu_func()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("rights_parent_id", s.getRights_id()); + long countAdminRightsBase=this.count(queryWrapper); + if(countAdminRightsBase>0){ + shopStoreEmployeeRightsBase.setChildren(buildShopStoreEmployeeRightsBaseTree(this.list(queryWrapper), s.getRights_id())); + } + tree.add(shopStoreEmployeeRightsBase); + } + }); + return tree; + } + private List buildTree(List employeeRightsBaseList, Integer pid) { List tree = new ArrayList<>(); @@ -61,4 +127,6 @@ public class ShopStoreEmployeeRightsBaseServiceImpl extends BaseServiceImpl Date: Fri, 5 Dec 2025 12:01:11 +0800 Subject: [PATCH 76/81] =?UTF-8?q?=E8=A3=85=E4=BF=AE=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=8C=E4=B8=9A=E7=B1=BB=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/page/controller/admin/ShopPageAppController.java | 6 ++++-- .../suisung/mall/shop/page/service/ShopPageAppService.java | 2 +- .../mall/shop/page/service/impl/ShopPageAppServiceImpl.java | 3 ++- sql/shop/dev/20251205_ddl.sql | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 sql/shop/dev/20251205_ddl.sql diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java index db728f64..1abdd980 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/controller/admin/ShopPageAppController.java @@ -433,13 +433,14 @@ public class ShopPageAppController extends BaseControllerImpl { */ @RequestMapping(value = "/copyDiyByAppId", method = RequestMethod.POST) public CommonResult copyDiyByAppId(@RequestParam(name = "appId") Integer appId, - @RequestParam(name = "appName") String newAppName) { + @RequestParam(name = "appName") String newAppName, + @RequestParam(name = "appIndustry",required = false,defaultValue = "0") String appIndustry) { UserDto user = ContextUtil.getCurrentUser(); if (user == null) { throw new ApiUserException(I18nUtil._("用户信息异常!")); } - return CommonResult.success(shopPageAppService.copyDiyByAppId(appId, newAppName)); + return CommonResult.success(shopPageAppService.copyDiyByAppId(appId, newAppName,appIndustry)); } /** @@ -531,6 +532,7 @@ public class ShopPageAppController extends BaseControllerImpl { editShopPageApp.setIs_pulish(shopPageApp.getIs_pulish()); editShopPageApp.setApp_market_images(shopPageApp.getApp_market_images()); editShopPageApp.setTpl_image(shopPageApp.getTpl_image()); + editShopPageApp.setApp_industry(shopPageApp.getApp_industry()); shopPageAppService.edit(editShopPageApp); return CommonResult.success(); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java index ff367287..f7343b85 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java @@ -57,7 +57,7 @@ public interface ShopPageAppService extends IBaseService { CommonResult copyDiyByStore(Integer sourceStoreId, Integer tpl_id); - CommonResult copyDiyByAppId(Integer appId,String a); + CommonResult copyDiyByAppId(Integer appId,String newAppName,String appIndustry); CommonResult deletePageApp(Integer appId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java index 89ecc618..639e02bf 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java @@ -986,7 +986,7 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl sourceShopPageBaseQueryWrapper = new QueryWrapper<>(); diff --git a/sql/shop/dev/20251205_ddl.sql b/sql/shop/dev/20251205_ddl.sql new file mode 100644 index 00000000..9086bf43 --- /dev/null +++ b/sql/shop/dev/20251205_ddl.sql @@ -0,0 +1 @@ +ALTER table shop_page_app add app_industry char(2) not null default '0' COMMENT '行业类别:1超市,2数码家电, 3水果生鲜, 4烘培饮品, 5社区团购, 6时尚美妆, 7婴儿服饰, 8家居, 9汽车, 10酒店旅游, 11鲜花绿植, 12医药健康, 13工业五金, 14节日模板,0其他行业'; \ No newline at end of file From 89a326a05b29b946a6b9ae8fd6d04fac283f24a0 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Fri, 5 Dec 2025 13:03:30 +0800 Subject: [PATCH 77/81] =?UTF-8?q?=E5=BA=97=E9=93=BA=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=88=E5=90=8C=E7=9A=84=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=EF=BC=8C=E4=BF=AE=E5=A4=8D=E9=A1=BA=E4=B8=B0?= =?UTF-8?q?=E5=90=8C=E5=9F=8E=E5=8F=96=E6=B6=88=E8=AE=A2=E5=8D=95=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EsignContractFillingFileServiceImpl.java | 43 +++++----- .../impl/EsignContractServiceImpl.java | 2 +- .../controller/mobile/LakalaController.java | 2 +- .../impl/ShopOrderBaseServiceImpl.java | 40 ++++----- .../impl/ShopOrderReturnServiceImpl.java | 25 +++--- .../service/SFExpressApiService.java | 20 ++--- .../service/impl/SFExpressApiServiceImpl.java | 81 +++++++++++++++---- .../impl/ShopStoreBaseServiceImpl.java | 6 ++ .../impl/ShopStoreSfOrderServiceImpl.java | 11 ++- pom.xml | 6 -- 10 files changed, 146 insertions(+), 90 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java index cecc2b57..f39b49d3 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractFillingFileServiceImpl.java @@ -104,55 +104,54 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl() {{ @@ -407,7 +406,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl 0; - log.info("合同文件生成完成, storeId: {}, 总模版数: {}, 成功处理数: {}, 结果: {}", + log.info("[合同生成] 商家合同文件全部生成完毕, storeId: {}, 总模板数: {}, 成功处理数: {}, 最终结果: {}", storeId, templates.size(), successCnt, result); return result; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java index fbfa2ae5..e5147939 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignContractServiceImpl.java @@ -202,7 +202,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl receiveCompleteNotify(HttpServletRequest request) { // 完整地址: https://mall.gpxscs.cn/api/mobile/shop/lakala/trans/receive/completeNotify JSONObject resp = lakalaPayService.receiveCompleteNotify(request); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 97d9b323..97ea60b3 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -5022,7 +5022,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_id", shopOrderId); + ShopOrderReturn shopOrderReturn = findOne(queryWrapper); + if (shopOrderReturn == null) { + logger.error("[顺丰超时自动退款] 订单信息异常,未找到退货单: shopOrderId={}", shopOrderId); + return false; + } + + if (ObjectUtil.equal(shopOrderReturn.getReturn_state_id(), StateCode.RETURN_PROCESS_FINISH) + || ObjectUtil.equal(shopOrderReturn.getReturn_is_paid(), CommonConstant.Enable)) { + logger.warn("[顺丰超时自动退款] 订单之前已处理完成,请勿重复处理: shopOrderId={}", shopOrderId); + return true; + } + // 对已存在部分退款的订单,进行剩余商品的全部退款 CommonResult commonResult = addRemainingItems(shopOrderId, true, remark); commonResult.checkFenResult(); logger.debug("[顺丰超时自动退款] 整单退货申请创建成功: shopOrderId={}", shopOrderId); - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("order_id", shopOrderId); - ShopOrderReturn shopOrderReturn = findOne(queryWrapper); - - if (shopOrderReturn == null) { - logger.error("[顺丰超时自动退款] 订单信息异常,未找到退货单: shopOrderId={}", shopOrderId); - throw new ApiException(I18nUtil._("订单信息异常!")); - } - shopOrderReturn.setReturn_flag(0); // 0-不用退货;1-需要退货 shopOrderReturn.setReturn_buyer_message(remark); shopOrderReturn.setReturn_store_message(remark); @@ -1886,7 +1891,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl updateWrapper = new QueryWrapper<>(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java index c6898d0a..73f6e8d2 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java @@ -164,6 +164,14 @@ public interface SFExpressApiService { */ ThirdApiRes notifyProductReady(Map params); + /** + * 订单实时信息查询 + * https://openic.sf-express.com/open/api/external/getorderstatus?sign=$sign + * + * @param sfOrderId + * @return + */ + ThirdApiRes getOrderStatus(String sfOrderId); // *********** 顺丰同城回调相关业务 **************** @@ -194,18 +202,6 @@ public interface SFExpressApiService { */ ThirdApiRes receiveOrderCompleteNotify(String jsonData, String sign); -// -// /** -// * 个推推送消息到员工 -// * -// * @param storeId -// * @param orderId -// * @param message -// * @param payloadJson -// * @return -// */ -// void pushMessageToStoreEmployee(Integer storeId, String orderId, String message, String payloadJson); - /** * 商家自行配送发货 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java index 701b3620..b4e5af13 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java @@ -675,9 +675,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { public ThirdApiRes cancelOrder(String orderId, Integer cancelCode, String cancelReason) { Map params = buildCommonParams(); params.put("order_id", shopStoreSfOrderService.getSfOrderIdByShopOrderId(orderId)); // 商家 orderId 转 顺丰的订单号 + params.put("cancel_type", 1); //1、顺丰订单号 2、商家订单号 if (StrUtil.isNotBlank(cancelReason) && cancelCode != null) { - params.put("cancel_code", orderId); - params.put("cancel_reason", orderId); + params.put("cancel_code", cancelCode); + params.put("cancel_reason", cancelReason); } return cancelOrder(params); } @@ -691,18 +692,33 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { @Override @Transactional public ThirdApiRes cancelOrder(Map params) { - logger.info("[顺丰] 开始取消订单流程"); + logger.info("[取消顺丰订单] 开始取消顺丰订单流程"); // 1. 参数校验 if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) { - logger.warn("[顺丰] 取消订单参数校验失败: 参数为空或缺少order_id"); + logger.warn("[取消顺丰订单] 取消订单参数校验失败: 参数为空或缺少order_id"); return new ThirdApiRes().fail(1003, "请求参数有误!"); } try { // 2. 获取顺丰订单号 String sfOrderId = params.get("order_id").toString(); - logger.debug("[顺丰] 准备取消订单: sfOrderId={}", sfOrderId); + logger.debug("[取消顺丰订单] 准备取消订单: sfOrderId={}", sfOrderId); + + // 先实时查询顺丰订单状态 + ThirdApiRes thirdApiRes = getOrderStatus(sfOrderId); + if (thirdApiRes != null && ObjectUtil.equal(thirdApiRes.getError_code(), 0)) { + Object resultObj = thirdApiRes.getResult(); + if (resultObj != null) { + JSONObject result = JSONUtil.parseObj(resultObj); + Integer orderStatus = result.getInt("order_status"); + if (orderStatus != null && + (ObjectUtil.equal(orderStatus, SFExpressConstant.Cons_CanceledOrder) || + ObjectUtil.equal(orderStatus, SFExpressConstant.Cons_CancelingOrder))) { + return new ThirdApiRes().success("订单已取消过!"); + } + } + } // 3. 添加公共参数 params.putAll(buildCommonParams()); @@ -710,34 +726,34 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { // 4. 调用顺丰取消订单接口 String sendUrl = buildUrl("cancelorder", paramJSON); - logger.debug("[顺丰] 调用取消订单接口: url={}, params={}", sendUrl, paramJSON); + logger.debug("[取消顺丰订单] 调用取消订单接口: url={}, params={}", sendUrl, paramJSON); String responseStr = HttpUtil.post(sendUrl, paramJSON); if (StrUtil.isBlank(responseStr)) { - logger.error("[顺丰] 取消订单接口调用失败: 无返回值, sfOrderId={}", sfOrderId); + logger.error("[取消顺丰订单] 取消订单接口调用失败: 无返回值, sfOrderId={}", sfOrderId); return new ThirdApiRes().fail(2, "顺丰同城:无返回值!"); } // 5. 解析接口响应 ThirdApiRes sfExpressApiRes = JsonUtil.json2object(responseStr, ThirdApiRes.class); if (sfExpressApiRes == null) { - logger.error("[顺丰] 取消订单接口响应解析失败: {}, sfOrderId={}", responseStr, sfOrderId); + logger.error("[取消顺丰订单] 取消订单接口响应解析失败: {}, sfOrderId={}", responseStr, sfOrderId); return new ThirdApiRes().fail(2, "顺丰同城:响应解析失败!"); } // 6. 检查接口调用结果 if (!sfExpressApiRes.getError_code().equals(0)) { - logger.error("[顺丰] 取消订单接口调用失败: errorCode={}, errorMsg={}, sfOrderId={}", + logger.error("[取消顺丰订单] 取消订单接口调用失败: errorCode={}, errorMsg={}, sfOrderId={}", sfExpressApiRes.getError_code(), sfExpressApiRes.getError_msg(), sfOrderId); return new ThirdApiRes().fail(2, sfExpressApiRes.getError_msg()); } - logger.info("[顺丰] 顺丰接口取消订单成功: sfOrderId={}", sfOrderId); + logger.info("[取消顺丰订单] 顺丰接口取消订单成功: sfOrderId={}", sfOrderId); // 7. 检查本地订单状态 - ShopStoreSfOrder existingOrder = shopStoreSfOrderService.getByShopOrderId(sfOrderId); + ShopStoreSfOrder existingOrder = shopStoreSfOrderService.getBySfOrderId(sfOrderId); if (existingOrder == null) { - logger.error("[顺丰] 本地订单不存在: sfOrderId={}", sfOrderId); + logger.error("[取消顺丰订单] 本地订单不存在: sfOrderId={}", sfOrderId); return new ThirdApiRes().fail(2, "订单不存在!"); } @@ -745,7 +761,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { if (existingOrder.getOrder_status() != null && (existingOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELED) || existingOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELING))) { - logger.info("[顺丰] 订单已处于取消状态,无需重复操作: sfOrderId={}, status={}", + logger.info("[取消顺丰订单] 订单已处于取消状态,无需重复操作: sfOrderId={}, status={}", sfOrderId, existingOrder.getOrder_status()); return new ThirdApiRes().success("订单已取消过!"); } @@ -758,15 +774,15 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { Boolean updateSuccess = shopStoreSfOrderService.updateShopStoreSfOrderStatus(updateOrder); if (!updateSuccess) { - logger.error("[顺丰] 更新本地订单状态失败: sfOrderId={}", sfOrderId); + logger.error("[取消顺丰订单] 更新本地订单状态失败: sfOrderId={}", sfOrderId); throw new ApiException(_("取消顺丰订单失败!")); } - logger.info("[顺丰] 本地订单状态更新成功: sfOrderId={}", sfOrderId); + logger.info("[取消顺丰订单] 本地订单状态更新成功: sfOrderId={}", sfOrderId); return sfExpressApiRes; } catch (Exception e) { - logger.error("[顺丰] 取消订单过程中发生异常: ", e); + logger.error("[取消顺丰订单] 取消订单过程中发生异常: ", e); return new ThirdApiRes().fail(-1, "系统异常: " + e.getMessage()); } } @@ -974,6 +990,39 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { return JsonUtil.json2object(retRespStr, ThirdApiRes.class); } + /** + * 订单实时信息查询 + * https://openic.sf-express.com/open/api/external/getorderstatus?sign=$sign + * + * @param sfOrderId + * @return + */ + @Override + public ThirdApiRes getOrderStatus(String sfOrderId) { + if (StrUtil.isBlank(sfOrderId)) { + return new ThirdApiRes().fail(1003, "缺少必要参数!"); + } + + Map params = buildCommonParams(); + params.put("order_id", sfOrderId); + params.put("order_type", 1);//查询订单ID类型:1、顺丰订单号 2、商家订单号 + + + // 转换 json 字符串参数 + String paramJSON = JsonUtil.toJSONString(params); + logger.debug("订单实时信息查询:" + paramJSON); + + // 根据参数生成请求签名 + String send_url = buildUrl("getorderstatus", paramJSON); + String retRespStr = HttpUtil.post(send_url, paramJSON); + if (StrUtil.isBlank(retRespStr)) { + logger.error("顺丰同城:订单实时信息查询,无返回值!"); + return new ThirdApiRes().fail(-1, "顺丰同城:无返回值!"); + } + + return JsonUtil.json2object(retRespStr, ThirdApiRes.class); + } + /** * 接收顺丰原因订单取消回调 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java index a941e594..4c541f73 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java @@ -1538,6 +1538,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl) data.get("items"), true)); @@ -1586,6 +1589,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl wrapper = new QueryWrapper<>(); - wrapper.eq("shop_order_id", shopOrderId); - return getOne(wrapper); + + if (StrUtil.startWith(shopOrderId, "JS")) { // 顺丰同城的订单号标志 + return getBySfOrderId(shopOrderId); + } else { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("shop_order_id", shopOrderId); + return getOne(wrapper); + } } /** diff --git a/pom.xml b/pom.xml index 993e72b7..68a9333d 100644 --- a/pom.xml +++ b/pom.xml @@ -581,7 +581,6 @@ true ${docker.ca} - openjdk:8-jre @@ -600,11 +599,6 @@ ["sh", "-c", "mkdir -p /tmp /app/temp /root/nacos/naming/public && chmod -R 777 /tmp /app/temp /root/nacos && java -Djava.io.tmpdir=/app/temp -Dnacos.naming.cache.dir=/root/nacos/naming -jar -Xms256m -Xmx512m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseContainerSupport -XX:MaxRAMPercentage=60.0 -XX:+UseSerialGC -XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=60 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:./gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -Dspring.profiles.active=${spring.profile} -Duser.timezone=Asia/Shanghai /${project.build.finalName}.jar"] - - - - - / From 7a26bdec4915d1735fa6a1afabe4951b88c33884 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Fri, 5 Dec 2025 14:20:33 +0800 Subject: [PATCH 78/81] =?UTF-8?q?=E8=A3=85=E4=BF=AE=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=8C=E4=B8=9A=E7=B1=BB=E5=88=AB,?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/suisung/mall/common/modules/page/ShopPageApp.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java index 8ed2f193..ae5aace8 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/page/ShopPageApp.java @@ -82,4 +82,7 @@ public class ShopPageApp implements Serializable { @ApiModelProperty(value = "市场展示图片,[{'imageUrl:'','description':''}") private String app_market_images; + + @ApiModelProperty(value = "行业类别:1超市,2数码家电, 3水果生鲜, 4烘培饮品, 5社区团购, 6时尚美妆, 7婴儿服饰, 8家居, 9汽车, 10酒店旅游, 11鲜花绿植, 12医药健康, 13工业五金, 14节日模板,0其他行业") + private String app_industry; } From a53ccaadc7ea8d59ea46f06784aad5be4739de8a Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Fri, 5 Dec 2025 15:54:01 +0800 Subject: [PATCH 79/81] =?UTF-8?q?=E7=BC=96=E8=BE=91=E8=A3=85=E4=BF=AEjs?= =?UTF-8?q?=E4=BC=A0=E5=85=A5app=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mall-shop/src/main/resources/static/diy/js/diy.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mall-shop/src/main/resources/static/diy/js/diy.js b/mall-shop/src/main/resources/static/diy/js/diy.js index c439732b..2b7a9c02 100644 --- a/mall-shop/src/main/resources/static/diy/js/diy.js +++ b/mall-shop/src/main/resources/static/diy/js/diy.js @@ -17703,7 +17703,8 @@ type: _x41903[298], url: SYS[_x41903[990]][_x41903[4411]] + _x41903[4449], data: { - page_type: 3 + page_type: 3, + app_id: $('#app_id').val() }, contentType: _x41903[672], dataType: _x41903[724], From f9192c74ff1ef8862da749fca0138876b8b8ee8c Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Fri, 5 Dec 2025 15:57:39 +0800 Subject: [PATCH 80/81] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=96=E5=8D=95?= =?UTF-8?q?=E5=8F=B7=E9=80=BB=E8=BE=91=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../number/service/ShopNumberSeqService.java | 9 ++ .../impl/ShopNumberSeqServiceImpl.java | 104 ++++++++++++------ .../impl/ShopOrderBaseServiceImpl.java | 23 ++-- .../impl/ShopOrderInfoServiceImpl.java | 28 +++-- 4 files changed, 113 insertions(+), 51 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java index 662505bb..cb5bd39a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java @@ -2,6 +2,7 @@ package com.suisung.mall.shop.number.service; import com.suisung.mall.common.modules.number.ShopNumberSeq; import com.suisung.mall.core.web.service.IBaseService; +import org.springframework.data.util.Pair; import java.util.List; @@ -17,6 +18,14 @@ public interface ShopNumberSeqService extends IBaseService { String createNextSeq(String prefix); + /** + * 创建下一个编号(键值对) + * + * @param prefix 前缀 + * @return 序号和完整编号 + */ + Pair createNextSeqPair(String prefix); + Long createNextNo(String prefix); List batchCreateNextNo(String seqName, int batchSize); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java index 20b9bb23..a2ead0e8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java @@ -27,6 +27,7 @@ import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -125,6 +126,44 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl createNextSeqPair(String prefix) { + String ymd = DateUtil.format(new Date(), "yyyyMMdd"); + String id = String.format("%s_%s_", prefix, ymd); + ShopNumberSeq shopNumberSeq = this.baseMapper.selectById(id); + if (shopNumberSeq == null) { + shopNumberSeq = new ShopNumberSeq(); + shopNumberSeq.setPrefix(id); + shopNumberSeq.setNumber(1L); + if (!save(shopNumberSeq)) { + return null; + } + } + + String order_id = String.format("%s_%s_%s", prefix, ymd, shopNumberSeq.getNumber()); + shopNumberSeq.setPrefix(id); + boolean flag = edit(shopNumberSeq); + if (flag) { + return Pair.of(shopNumberSeq.getNumber(), order_id); + } + + return null; + } + /** * 得到下一个Id * @@ -280,12 +319,12 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl getBatchSpecItemId(int batchSize) { + public List getBatchSpecItemId(int batchSize) { // 定义锁的key,这个key在所有服务实例中必须一致 String lockKey = "LOCK:" + RedisKey.STOREDATASPECITEMID; // 2. 获取分布式锁对象 @@ -330,12 +369,12 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl getBatchLibraryProductId(int batchSize) { + public List getBatchLibraryProductId(int batchSize) { // 定义锁的key,这个key在所有服务实例中必须一致 String lockKey = "LOCK:" + RedisKey.STOREDATALIBRARYID; // 2. 获取分布式锁对象 @@ -434,7 +473,7 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.select("max(page_id) as page_id"); ShopPageBase shopPageBase = shopPageBaseService.getOne(queryWrapper); @@ -493,41 +532,41 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl shopNumberSeqList=new ArrayList<>(); - QueryWrapper baseWrapper=new QueryWrapper<>(); + private void syncPrimaryKey() { + List shopNumberSeqList = new ArrayList<>(); + QueryWrapper baseWrapper = new QueryWrapper<>(); baseWrapper.select("MAX(product_id) as product_id"); - ShopProductBase shopProductBase= shopProductBaseService.getOne(baseWrapper); - Long productId= shopProductBase.getProduct_id(); + ShopProductBase shopProductBase = shopProductBaseService.getOne(baseWrapper); + Long productId = shopProductBase.getProduct_id(); //QueryWrapper baseSeWrapper=new QueryWrapper(); //baseSeWrapper.eq("prefix", "product_id"); - ShopNumberSeq shopNumberSeqBase= new ShopNumberSeq(); + ShopNumberSeq shopNumberSeqBase = new ShopNumberSeq(); shopNumberSeqBase.setPrefix("product_id"); shopNumberSeqBase.setNumber(productId); //shopNumberSeqServiceImpl.edit(shopNumberSeqBase,baseWrapper); //查询产品item - QueryWrapper itemQuery=new QueryWrapper<>(); + QueryWrapper itemQuery = new QueryWrapper<>(); itemQuery.select("MAX(item_id) as item_id"); - ShopProductItem shopProductItem= shopProductItemService.getOne(itemQuery); - Long itemtId=1L; - if(null!=shopProductItem){ - itemtId= shopProductItem.getItem_id(); + ShopProductItem shopProductItem = shopProductItemService.getOne(itemQuery); + Long itemtId = 1L; + if (null != shopProductItem) { + itemtId = shopProductItem.getItem_id(); } // QueryWrapper itemWrapper=new QueryWrapper(); //itemWrapper.eq("prefix", "item_id"); - ShopNumberSeq shopNumberSeqItem= new ShopNumberSeq(); + ShopNumberSeq shopNumberSeqItem = new ShopNumberSeq(); shopNumberSeqItem.setNumber(itemtId); shopNumberSeqItem.setPrefix("item_id"); shopNumberSeqList.add(shopNumberSeqBase); @@ -537,5 +576,4 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl seqPair = shopNumberSeqService.createNextSeqPair(type_code);// 位数的序号: DD_20251205_1 2025-12-05 1 + String order_id = seqPair.getSecond(); + Long seqNo = seqPair.getFirst(); // 序号: DD_20251205_1 得出 1 RootContext.bind(xid); List item_rows = new ArrayList(); @@ -6666,6 +6668,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); // 已发货,已签收 queryWrapper.in("order_state_id", StateCode.ORDER_STATE_SHIPPED, StateCode.ORDER_STATE_RECEIVED); - queryWrapper.eq("order_is_received",CommonConstant.Disable); + queryWrapper.eq("order_is_received", CommonConstant.Disable); // 默认7天,自动收货 // 配置了发货或已签收的订单,1天自动收货 Float order_autofinish_time = accountBaseConfigService.getConfig("order_autofinish_time", 7f); @@ -372,8 +372,8 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl Date: Fri, 5 Dec 2025 16:03:35 +0800 Subject: [PATCH 81/81] =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E6=96=B0=E5=A2=9E=E5=8F=82=E6=95=B0app=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/page/service/ShopPageAppService.java | 2 +- .../service/impl/ShopPageAppServiceImpl.java | 25 +++++++++++++------ .../service/impl/ShopPageBaseServiceImpl.java | 12 ++++++--- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java index f7343b85..fc004a73 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/ShopPageAppService.java @@ -49,7 +49,7 @@ public interface ShopPageAppService extends IBaseService { /** * */ - Map getApp(Integer subsite_id, Integer store_id, Integer tpl_id, Integer app_type); + Map getApp(Integer subsite_id, Integer store_id, Integer tpl_id, Integer app_type,Integer appId); Map getModuleTpl(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java index 639e02bf..5f6a56d6 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageAppServiceImpl.java @@ -136,7 +136,12 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl shopPageList = Convert.toList(Map.class, page_base.get("items")); @@ -609,15 +614,19 @@ public class ShopPageAppServiceImpl extends BaseServiceImpl shopPageAppQueryWrapper = new QueryWrapper<>(); - //权限判断 - shopPageAppQueryWrapper.eq("app_type", app_type); - shopPageAppQueryWrapper.eq("store_id", store_id); - shopPageAppQueryWrapper.eq("subsite_id", subsite_id); - shopPageAppQueryWrapper.eq("tpl_id", tpl_id); - shopPageAppQueryWrapper.eq("app_is_use",1);//使用中的模板 + if(ObjectUtil.isNotNull(appId)){ + shopPageAppQueryWrapper.eq("app_id", appId); + }else { + //权限判断 + shopPageAppQueryWrapper.eq("app_type", app_type); + shopPageAppQueryWrapper.eq("store_id", store_id); + shopPageAppQueryWrapper.eq("subsite_id", subsite_id); + shopPageAppQueryWrapper.eq("tpl_id", tpl_id); + shopPageAppQueryWrapper.eq("app_is_use",1);//使用中的模板 + } ShopPageApp shopPA = shopPageAppService.findOne(shopPageAppQueryWrapper); Map data = new HashMap(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java index 7d697301..af2faa09 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/ShopPageBaseServiceImpl.java @@ -158,9 +158,15 @@ public class ShopPageBaseServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq("store_id", store_id).eq("tpl_id", Convert.toInt(tpl_id)); - - ShopPageApp shopPageAppServiceOne = shopPageAppService.findOne(queryWrapper); - + queryWrapper.eq("app_is_use",1); + List shopPageAppList = shopPageAppService.list(queryWrapper); + if(shopPageAppList.isEmpty()){ + queryWrapper.clear(); + queryWrapper.eq("store_id", store_id).eq("tpl_id", Convert.toInt(tpl_id)); + shopPageAppList=shopPageAppService.list(queryWrapper); + } + ShopPageApp shopPageAppServiceOne =shopPageAppList.get(0); + //ShopPageApp shopPageAppServiceOne = shopPageAppService.findOne(queryWrapper); QueryWrapper baseQueryWrapper = new QueryWrapper<>(); baseQueryWrapper.eq("store_id", store_id).eq("app_id", shopPageAppServiceOne.getApp_id()).eq("page_index", 1);