From ef79fe601b56276128a242daa42ece40dceb2de4 Mon Sep 17 00:00:00 2001 From: liyj <1617420630@qq.com> Date: Fri, 20 Jun 2025 17:50:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=95=86=E5=93=81=E6=B4=BB?= =?UTF-8?q?=E5=8A=A8=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/Utils/BigDecimalFormatter.java | 29 +++ .../com/small/client/Utils/HttpUtils.java | 7 +- .../client/controller/WebController.java | 11 + .../java/com/small/client/dao/BaseDao.java | 95 ++++++++ .../java/com/small/client/dao/SxDataDao.java | 173 ++++++++++++-- .../java/com/small/client/dto/ActiveDto.java | 45 ++++ .../com/small/client/dto/ActiveMaxDes.java | 13 + .../com/small/client/dto/ActiveShopInfo.java | 44 ++++ .../service/SxDataAbst/SxDataAbstService.java | 4 +- .../small/client/service/SxDataService.java | 15 ++ .../client/service/imp/SxDataServiceImp.java | 98 +++++++- .../shop/sync/Utils/ActiveShopJsonUtils.java | 224 ++++++++++++++++++ 12 files changed, 736 insertions(+), 22 deletions(-) create mode 100644 client/src/main/java/com/small/client/Utils/BigDecimalFormatter.java create mode 100644 client/src/main/java/com/small/client/dto/ActiveDto.java create mode 100644 client/src/main/java/com/small/client/dto/ActiveMaxDes.java create mode 100644 client/src/main/java/com/small/client/dto/ActiveShopInfo.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/sync/Utils/ActiveShopJsonUtils.java diff --git a/client/src/main/java/com/small/client/Utils/BigDecimalFormatter.java b/client/src/main/java/com/small/client/Utils/BigDecimalFormatter.java new file mode 100644 index 00000000..d68b0695 --- /dev/null +++ b/client/src/main/java/com/small/client/Utils/BigDecimalFormatter.java @@ -0,0 +1,29 @@ +package com.small.client.Utils; + +import java.math.BigDecimal; + +public class BigDecimalFormatter { + public static String formatWithoutTrailingZeros(BigDecimal number) { + if (number == null) { + return null; + } + + // 去除末尾0并转换为普通字符串表示 + BigDecimal stripped = number.stripTrailingZeros(); + String result = stripped.toPlainString(); + + // 处理结果为负0的情况(返回"0"而不是"-0") + if (result.startsWith("-0")) { + if (result.indexOf('.') == -1) { + if (result.length() == 2) { // "-0" + return "0"; + } else if (result.matches("-0+")) { // "-000" + return "0"; + } + } else if (result.matches("-0\\.0*")) { // "-0.0" 或 "-0.00" + return "0"; + } + } + return result; + } +} diff --git a/client/src/main/java/com/small/client/Utils/HttpUtils.java b/client/src/main/java/com/small/client/Utils/HttpUtils.java index ef272821..7b7c29d2 100644 --- a/client/src/main/java/com/small/client/Utils/HttpUtils.java +++ b/client/src/main/java/com/small/client/Utils/HttpUtils.java @@ -1,6 +1,7 @@ package com.small.client.Utils; import cn.hutool.json.JSON; +import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.small.client.dto.StoreDbConfig; @@ -40,9 +41,12 @@ public class HttpUtils { public static final String URL_SYNC_GET_STOR_DATA_RELEASE="/shop/sync/third/syncStoreDataRelease";//库存同步 - public static final String URL_SYNC_GOODS_NOTICE_UPLOAD_TO_OSS="/shop/sync/third/uploudToCos";//通知上传文件到cos + public static final String URL_SYNC_ACTIVE="/shop/sync/third/syncAtive";//同步活动到服务器 + + public static final String URL_SYNC_ACTIVE_SHOP="/shop/sync/third/syncAtiveShop";//同步活动商品到服务器 + public static String postData(RestTemplate restTemplate, String url,Object modelObject){ // 创建表单参数 // MultiValueMap map = new LinkedMultiValueMap<>(); @@ -103,4 +107,5 @@ public class HttpUtils { return null; } + } diff --git a/client/src/main/java/com/small/client/controller/WebController.java b/client/src/main/java/com/small/client/controller/WebController.java index aede90eb..bbe2e707 100644 --- a/client/src/main/java/com/small/client/controller/WebController.java +++ b/client/src/main/java/com/small/client/controller/WebController.java @@ -93,4 +93,15 @@ public class WebController { sxDataService.syncStoreData(new DataBaseInfo(),sxDataService.getCommentModel()); } + + @RequestMapping("/syncActives") + public void syncActives(){ + sxDataService.syncAtive(new DataBaseInfo(),sxDataService.getCommentModel()); + } + + @RequestMapping("/syncActives") + public void syncAtiveShops(){ + sxDataService.syncAtiveShops(new DataBaseInfo(),sxDataService.getCommentModel()); + } + } 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 3415ce14..7d50de06 100644 --- a/client/src/main/java/com/small/client/dao/BaseDao.java +++ b/client/src/main/java/com/small/client/dao/BaseDao.java @@ -244,5 +244,100 @@ public class BaseDao { return resultDto; } + /** + * 带分页数据 + * @param ip + * @param username + * @param password + * @param dataBaseName + * @param pageNo + * @param pageSize + * @return + */ + public ResultDto baseFindSpecListPage(String ip, String username, String password,Integer portNumber, String dataBaseName, int pageNo, int pageSize,String where){ + 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 %s) as rowId,* from %s %s" + +// " ) as r where rowId between %s and %s"; + + String sql = "select * from( \n" + + " select \n" + + " ROW_NUMBER() OVER(order by t.flow_no) as rownum, \n" + + " t.* \n" + + " from \n" + + " ( \n" + + " select \n" + + " ROW_NUMBER() OVER(partition by b.start_date, \n" + + " b.end_date, \n" + + " b.special_type,b.discount \n" + + " ORDER BY \n" + + " b.start_date) as rowId, \n" + + " b.* \n" + + " from \n" + + " t_rm_spec_price b %s \n" + + " )t \n" + + " where \n" + + " t.rowId = 1 \n" + + " )t where rownum between %s and %s "; + + 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.baseFindSpecListPage",e.getMessage()); + throw new RuntimeException(e); + } + resultDto.setResultSet(rs); + resultDto.setConnection(connection); + return resultDto; + } + + public Integer getBaseSpecTotal(String ip, String username, String password,Integer portNumber, String dataBaseName,String where){ + int total=0; + Connection connection=getConnection(ip,username,password,portNumber,dataBaseName); + try { + String sql = "select\n" + + " COUNT(1)\n" + + "from\n" + + " (\n" + + " select\n" + + " ROW_NUMBER() OVER(partition by b.start_date,\n" + + " b.end_date,\n" + + " b.special_type\n" + + " ORDER BY\n" + + " b.start_date) as rowId,\n" + + " b.*\n" + + " from\n" + + " t_rm_spec_price b %s \n" + + ")t\n" + + "where\n" + + " t.rowId = 1"; + sql=String.format(sql,where); + log.info(sql); + PreparedStatement ps= connection.prepareStatement(sql); + ResultSet rs=ps.executeQuery(); + while (rs.next()){ + total=rs.getInt(1); + } + } catch (SQLException e) { + log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.getBaseSpecTotal",e.getMessage()); + throw new RuntimeException(e); + } + finally { + try { + connection.close(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + return total; + } + } 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 bcb72e3c..264a7944 100644 --- a/client/src/main/java/com/small/client/dao/SxDataDao.java +++ b/client/src/main/java/com/small/client/dao/SxDataDao.java @@ -2,6 +2,8 @@ package com.small.client.dao; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; +import com.small.client.Utils.BigDecimalFormatter; import com.small.client.dto.*; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -498,28 +500,169 @@ public class SxDataDao extends BaseDao{ } } } + /** - * 更新库存为负数的数据,避免超卖 + *获取促销活动价格 时段特价单 * @param dataBaseInfo - * @throws SQLException + * @return */ - public void baseUpdateImBrancStock(DataBaseInfo dataBaseInfo) throws SQLException { - Connection connection=getConnection(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword() - ,dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName()); - String sql = "update t_im_branch_stock set stock_qty= 0,oper_date=? where stock_qty<0"; - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - try (PreparedStatement ps = connection.prepareStatement(sql)) { - ps.setTimestamp(1,timestamp); - ps.executeUpdate(); - }catch (RuntimeException e){ - throw new RuntimeException(e.getMessage()); + public List getActiveList(DataBaseInfo dataBaseInfo,int pageNo,int pageSize){ + String where=dataBaseInfo.getWhere()+" and special_type in('6','G','0','E')"; + ResultDto resultDto=baseFindSpecListPage(dataBaseInfo.getIp() + ,dataBaseInfo.getUserName() + ,dataBaseInfo.getPassword() + ,dataBaseInfo.getDbPort() + ,dataBaseInfo.getDataBaseName() + ,pageNo + ,pageSize + ,where); + ResultSet rs= resultDto.getResultSet(); + List activeDtos=new ArrayList<>(); + try { + while (rs.next()) { + ActiveDto activeDto=new ActiveDto(); + String specialType=rs.getString("special_type").trim(); + if(specialType.equals("6")||specialType.equals("G")){//折扣 + BigDecimal discount=rs.getBigDecimal("discount"); + String discountStr=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("discount").multiply(new BigDecimal(10))); + activeDto.setActivityName(rs.getString(discountStr+"折商品")); + activeDto.setActivityTypeId(2); + activeDto.setDiscount(discount); + } + if(specialType.equals("0")){//特价(秒杀) + activeDto.setActivityName(rs.getString("限时特价秒杀")); + activeDto.setActivityTypeId(1); + } + if(specialType.equals("E")){//满减 + String total1=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("old_price")); + String max1=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("spe_price")); + String max2=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("spe_price").add(rs.getBigDecimal("new_price1"))); + String total2=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("old_price").add(rs.getBigDecimal("old_price1"))); + activeDto.setActivityName(rs.getString("满")+total1+"减"+max1+",满"+total2+"减"+max2); + List activeMaxDesList=new ArrayList<>(); + ActiveMaxDes activeMaxDes=new ActiveMaxDes(); + activeMaxDes.setMaxNum(rs.getBigDecimal("spe_price")); + activeMaxDes.setTotal(rs.getBigDecimal("old_price")); + activeMaxDesList.add(activeMaxDes); + BigDecimal new_price1=rs.getBigDecimal("new_price1"); + BigDecimal old_price1=rs.getBigDecimal("old_price1"); + if(new_price1.compareTo(BigDecimal.ZERO)>0&&old_price1.compareTo(BigDecimal.ZERO)>0){ + ActiveMaxDes activeMaxDes2=new ActiveMaxDes(); + activeMaxDes2.setMaxNum(rs.getBigDecimal("spe_price").add(rs.getBigDecimal("new_price1"))); + activeMaxDes2.setTotal(rs.getBigDecimal("old_price").add(rs.getBigDecimal("old_price1"))); + activeMaxDesList.add(activeMaxDes2); + } + activeDto.setActivityTypeId(3); + activeDto.setActiveMaxDesList(activeMaxDesList); + } + activeDto.setActivityReleasetime(rs.getDate("oper_date")); + activeDto.setActivityStarttime(rs.getDate("start_date")); + activeDto.setActivityEndtime(rs.getDate("end_date")); + if(DateUtil.compare(activeDto.getActivityEndtime(),DateUtil.date())>0){ + activeDto.setActivityState(1);//正常进行中 + }else { + activeDto.setActivityState(2);//结束 + } + activeDtos.add(activeDto); + } } catch (SQLException e) { throw new RuntimeException(e); - }finally { - if (connection!=null){ - connection.close(); + } finally { + try { + resultDto.getConnection().close(); + } catch (SQLException e) { + throw new RuntimeException(e); } } + return activeDtos; + } + + /** + * + * @param dataBaseInfo + * @return + */ + public Integer getActiveCount(DataBaseInfo dataBaseInfo){ + String where=dataBaseInfo.getWhere()+" and special_type in('6','G','0','E')"; + return getBaseSpecTotal(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(), + where); + } + + /** + * + * @param dataBaseInfo + * @return + */ + public Integer getAllSpecCount(DataBaseInfo dataBaseInfo){ + String where=dataBaseInfo.getWhere()+" and special_type in('6','G','0','E')"; + return getBaseTotal(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(), + dataBaseInfo.getDataBaseName(),T_RM_SPEC_PRICE,where); + } + + + /** + * 折扣商品 + * @param dataBaseInfo + * @return + */ + public List getAllSpecPriceList(DataBaseInfo dataBaseInfo,int pageNo,int pageSize){ + String where=dataBaseInfo.getWhere()+" and special_type in('6','G','0','E')"; + ResultDto resultDto=baseFindListPage(dataBaseInfo.getIp() + ,dataBaseInfo.getUserName() + ,dataBaseInfo.getPassword() + ,dataBaseInfo.getDbPort() + ,dataBaseInfo.getDataBaseName() + ,T_RM_SPEC_PRICE + ,ITEM_NO + ,pageNo + ,pageSize + ,where); + ResultSet rs= resultDto.getResultSet(); + List activeShopInfos=new ArrayList<>(); + try { + while (rs.next()) { + ActiveShopInfo activeShopInfo=new ActiveShopInfo(); + activeShopInfo.setItemNo(rs.getString("item_no").trim()); + String specialType=rs.getString("special_type").trim(); + if(specialType.equals("6")||specialType.equals("G")){//折扣 + BigDecimal discount=rs.getBigDecimal("discount"); + String discountStr=BigDecimalFormatter.formatWithoutTrailingZeros(discount.multiply(new BigDecimal(10))); + activeShopInfo.setActivityName(rs.getString(discountStr+"折商品")); + activeShopInfo.setActivityTypeId(2); + } + if(specialType.equals("0")){//特价(秒杀) + activeShopInfo.setActivityName(rs.getString("限时特价秒杀")); + activeShopInfo.setOldPrice(rs.getBigDecimal("old_price")); + activeShopInfo.setSpecPrice(rs.getBigDecimal("spec_price")); + activeShopInfo.setActivityTypeId(1); + } + if(specialType.equals("E")){//满减 + String total1=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("old_price")); + String max1=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("spe_price")); + String max2=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("spe_price").add(rs.getBigDecimal("new_price1"))); + String total2=BigDecimalFormatter.formatWithoutTrailingZeros(rs.getBigDecimal("old_price").add(rs.getBigDecimal("old_price1"))); + activeShopInfo.setActivityName(rs.getString("满")+total1+"减"+max1+",满"+total2+"减"+max2); + activeShopInfo.setActivityTypeId(3); + } + activeShopInfo.setActivityStarttime(rs.getDate("start_date")); + activeShopInfo.setActivityEndtime(rs.getDate("end_date")); + if(DateUtil.compare(activeShopInfo.getActivityEndtime(),DateUtil.date())>0){ + activeShopInfo.setActivityState(1);//正常进行中 + }else { + activeShopInfo.setActivityState(2);//结束 + } + activeShopInfos.add(activeShopInfo); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + try { + resultDto.getConnection().close(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + return activeShopInfos; } } diff --git a/client/src/main/java/com/small/client/dto/ActiveDto.java b/client/src/main/java/com/small/client/dto/ActiveDto.java new file mode 100644 index 00000000..42e6a100 --- /dev/null +++ b/client/src/main/java/com/small/client/dto/ActiveDto.java @@ -0,0 +1,45 @@ +package com.small.client.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Data +public class ActiveDto implements Serializable { + + + @ApiModelProperty(value = "活动名称") + private String activityName; + + @ApiModelProperty(value = "活动类型 1秒杀;2单件折扣,3满减") + private Integer activityTypeId; + + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty(value = "活动开始时间") + private Date activityStarttime; + + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty(value = "活动结束时间") + private Date activityEndtime; + + @ApiModelProperty(value = "活动状态(ENUM):0-未开启;1-正常;2-已结束;3-管理员关闭;4-商家关闭") + private Integer activityState; + + @ApiModelProperty(value = "发布时间") + private Date activityReleasetime; + + @ApiModelProperty(value = "折扣") + private BigDecimal discount; + + @ApiModelProperty(value = "满减规则") + private List activeMaxDesList; + +} diff --git a/client/src/main/java/com/small/client/dto/ActiveMaxDes.java b/client/src/main/java/com/small/client/dto/ActiveMaxDes.java new file mode 100644 index 00000000..6fe4df3f --- /dev/null +++ b/client/src/main/java/com/small/client/dto/ActiveMaxDes.java @@ -0,0 +1,13 @@ +package com.small.client.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class ActiveMaxDes { + + private BigDecimal total; + + private BigDecimal maxNum; +} diff --git a/client/src/main/java/com/small/client/dto/ActiveShopInfo.java b/client/src/main/java/com/small/client/dto/ActiveShopInfo.java new file mode 100644 index 00000000..9ee1b0d8 --- /dev/null +++ b/client/src/main/java/com/small/client/dto/ActiveShopInfo.java @@ -0,0 +1,44 @@ +package com.small.client.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class ActiveShopInfo { + + @ApiModelProperty(value = "商品编号") + private String itemNo; + + @ApiModelProperty(value = "活动名称") + private String activityName; + + @ApiModelProperty(value = "活动类型 1秒杀;2单件折扣,3满减") + private Integer activityTypeId; + + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty(value = "活动开始时间") + private Date activityStarttime; + + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty(value = "活动结束时间") + private Date activityEndtime; + + @ApiModelProperty(value = "折扣") + private BigDecimal discount; + + @ApiModelProperty(value = "活动状态(ENUM):0-未开启;1-正常;2-已结束;3-管理员关闭;4-商家关闭") + private Integer activityState; + + @ApiModelProperty(value = "原价") + private BigDecimal oldPrice;//原价 + + @ApiModelProperty(value = "折后价") + private BigDecimal specPrice;//折后价 +} 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 3f43eca5..a9fc47ba 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 @@ -133,8 +133,8 @@ public abstract class SxDataAbstService { for (SxSyncGoods sxSyncGood:sxSyncGoods){ sxGoosModel=new SxGoosModel(); sxGoosModel.setProduct_name(sxSyncGood.getItem_subname()); - sxGoosModel.setProduct_number(sxSyncGood.getItem_no().trim());// todo - sxGoosModel.setProduct_barcode(sxSyncGood.getItem_subno());// todo + sxGoosModel.setProduct_number(sxSyncGood.getItem_no().trim());// + sxGoosModel.setProduct_barcode(sxSyncGood.getItem_no().trim());// sxGoosModel.setFirst_category_name(commonCache.get(sxSyncGood.getSmall_cls_name()));// todo sxGoosModel.setSecond_category_name("");// todo diff --git a/client/src/main/java/com/small/client/service/SxDataService.java b/client/src/main/java/com/small/client/service/SxDataService.java index 80ea2bb9..19765801 100644 --- a/client/src/main/java/com/small/client/service/SxDataService.java +++ b/client/src/main/java/com/small/client/service/SxDataService.java @@ -57,4 +57,19 @@ public interface SxDataService { */ void syncStoreData(DataBaseInfo dataBaseInfo,CommentModel commentModel); + + /** + * 同步商品活动 + * @param commentModel + * @return + */ + void syncAtive(DataBaseInfo dataBaseInfo,CommentModel commentModel); + + /** + * 同步活动商品 + * @param commentModel + * @return + */ + void syncAtiveShops(DataBaseInfo dataBaseInfo,CommentModel commentModel); + } 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 b237f28e..7ef71749 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 @@ -35,6 +35,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.time.Duration; +import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -319,7 +321,8 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService List discountList= getDiscountFromCache(dataBaseInfo); List specPriceDtoList= getSpecPriceFromCache(dataBaseInfo); specPriceDtoList.addAll(discountList); - + Date tenMinutesAgo = Date.from(Instant.now());//刷新时间 + Date refreshDate= DateUtil.date(tenMinutesAgo); List folders=new ArrayList<>(); for (int i = 1; i <=pages; i++) { List sxSyncGoods= sxDataDao.findBditemInfoListPage(dataBaseInfo,i,SxDataDao.PAGESIZE); @@ -342,7 +345,8 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_GOODS_NOTICE_UPLOAD_TO_OSS +"?appKey="+commentModel.getAppKey() +"&sign="+commentModel.getSign() - +"&syncType="+DicEnum.MUAL_1.getCode(), + +"&syncType="+DicEnum.MUAL_1.getCode() + +"&refreshDate="+refreshDate, JSONUtil.parseArray(folders)); //folders.add(String.valueOf(4)); @@ -675,9 +679,95 @@ public class SxDataServiceImp extends SxDataAbstService implements SxDataService } } - private String checkUpdate(){ + @Override + public void syncAtive(DataBaseInfo dataBaseInfo, CommentModel commentModel) { + String where="where 1=1"; + Integer total =0; + if(DicEnum.SYNCTYPE_02.getCode().equals(dataBaseInfo.getSyncType())){ + if(StringUtils.isNotEmpty(commentModel.getSyncTime())){ + where+=" and b.modify_date>'"+commentModel.getSyncTime()+"' "; + where+=" or b.build_date>'"+commentModel.getSyncTime()+"' "; + } + if(StringUtils.isNotEmpty(dataBaseInfo.getOperDate())){ + where+=" and t.oper_date>'"+dataBaseInfo.getOperDate()+"' "; + } + } + dataBaseInfo.setWhere(where); + total = sxDataDao.getActiveCount(dataBaseInfo); + if(total==0){ + log.info("暂无活动同步"); + return; + } + // 总页数 + int pages = CommonUtil.getPagesCount(total, SxDataDao.PAGESIZE); + int syncCount =0; + String encryptedData= getPrimaryKey(); + Date tenMinutesAgo = Date.from(Instant.now());//刷新时间 + Date refreshDate= DateUtil.date(tenMinutesAgo); + for (int i = 1; i <=pages; i++) { + List activeDtos= sxDataDao.getActiveList(dataBaseInfo,i,SxDataDao.PAGESIZE); + String jsonString=""; + ObjectMapper objectMapper = new ObjectMapper(); + try { + jsonString = objectMapper.writeValueAsString(activeDtos); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + String code= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_ACTIVE + +"?primaryKey="+encryptedData, jsonString); + if (!HttpUtils.SUCCESSCODE.equals(code)) { + continue; + } + syncCount+=activeDtos.size(); + } + log.info("成功同步活动数据:"+syncCount); - return null; } + @Override + public void syncAtiveShops(DataBaseInfo dataBaseInfo, CommentModel commentModel) { + String where="where 1=1"; + Integer total =0; + if(DicEnum.SYNCTYPE_02.getCode().equals(dataBaseInfo.getSyncType())){ + if(StringUtils.isNotEmpty(commentModel.getSyncTime())){ + where+=" and b.modify_date>'"+commentModel.getSyncTime()+"' "; + where+=" or b.build_date>'"+commentModel.getSyncTime()+"' "; + } + if(StringUtils.isNotEmpty(dataBaseInfo.getOperDate())){ + where+=" and t.oper_date>'"+dataBaseInfo.getOperDate()+"' "; + } + } + dataBaseInfo.setWhere(where); + total = sxDataDao.getAllSpecCount(dataBaseInfo); + if(total==0){ + log.info("暂无活动商品同步"); + return; + } + // 总页数 + int pages = CommonUtil.getPagesCount(total, SxDataDao.PAGESIZE); + int syncCount =0; + String encryptedData= getPrimaryKey(); + Date tenMinutesAgo = Date.from(Instant.now());//刷新时间 + Date refreshDate= DateUtil.date(tenMinutesAgo);//todo 要记录刷新时间 + for (int i = 1; i <=pages; i++) { + List activeDtos= sxDataDao.getAllSpecPriceList(dataBaseInfo,i,SxDataDao.PAGESIZE); + String jsonString=""; + ObjectMapper objectMapper = new ObjectMapper(); + try { + jsonString = objectMapper.writeValueAsString(activeDtos); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + String code= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_ACTIVE_SHOP + +"?primaryKey="+encryptedData, jsonString); + if (!HttpUtils.SUCCESSCODE.equals(code)) { + continue; + } + syncCount+=activeDtos.size(); + } + log.info("成功同步活动商品数据:"+syncCount); + + } + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sync/Utils/ActiveShopJsonUtils.java b/mall-shop/src/main/java/com/suisung/mall/shop/sync/Utils/ActiveShopJsonUtils.java new file mode 100644 index 00000000..dae7ce58 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sync/Utils/ActiveShopJsonUtils.java @@ -0,0 +1,224 @@ +package com.suisung.mall.shop.sync.Utils; + + + +import cn.hutool.json.JSONUtil; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.*; + +public class ActiveShopJsonUtils { + + public static final String FULLREDUCE="fullReduce";//满减 + public static final String DISCOUNT="discount";//折扣 + public static final String SECKILL="seckill";//秒杀 + /** + * 生成满减活动的规则 + * @param jsonArray + * @return + */ + public static String getRules(cn.hutool.json.JSONArray jsonArray){ + cn.hutool.json.JSONObject activity_rule = new cn.hutool.json.JSONObject(); + List rules = new ArrayList<>(); + for (int i = 0; i < jsonArray.size(); i++) { + cn.hutool.json.JSONObject jsonObject = jsonArray.getJSONObject(i); + Map rule = new HashMap(); + rule.put("total", BigDecimalFormatter.formatWithoutTrailingZeros(jsonObject.getBigDecimal("total"))); + rule.put("max_num", BigDecimalFormatter.formatWithoutTrailingZeros(jsonObject.getBigDecimal("maxNum"))); + rule.put("item", new ArrayList()); + rules.add(rule); + activity_rule.put("rule", rules); + } + return JSONUtil.toJsonStr(activity_rule); + } + + /** + * 构建促销规则JSON(支持批量添加商品) + * @param type 促销类型: fullReduce(满减), discount(折扣), seckill(秒杀) + * @param dbRuleStr 数据库中的规则字符串 + * @param newItems 要添加的新商品列表 + * @return 更新后的JSON字符串 + */ + public static String buildPromotionRule(String type, String dbRuleStr, List newItems) { + JSONObject ruleObj; + + // 解析或初始化基础JSON结构 + if (dbRuleStr == null || dbRuleStr.trim().isEmpty()) { + ruleObj = createBaseRule(type); + } else { + ruleObj = new JSONObject(dbRuleStr); + } + + // 根据类型处理商品数据 + switch (type) { + case FULLREDUCE: + handleFullReduce(ruleObj, newItems); + break; + case DISCOUNT: + handleDiscount(ruleObj, newItems); + break; + case SECKILL: + handleSeckill(ruleObj, newItems); + break; + default: + throw new IllegalArgumentException("不支持的促销类型: " + type); + } + + return ruleObj.toString(); + } + + // 创建基础规则结构 + private static JSONObject createBaseRule(String type) { + JSONObject ruleObj = new JSONObject(); + ruleObj.put("discount", new JSONArray()); + ruleObj.put("rule", new JSONArray()); + + JSONObject requirement = new JSONObject(); + JSONObject buy = new JSONObject(); + buy.put("item", new JSONArray()); + buy.put("subtotal", ""); + requirement.put("buy", buy); + ruleObj.put("requirement", requirement); + + // 满减类型添加默认规则 + if ("fullReduce".equals(type)) { + JSONObject ruleItem = new JSONObject(); + ruleItem.put("item", new JSONArray()); + ruleObj.getJSONArray("rule").put(ruleItem); + } + + return ruleObj; + } + + // 处理满减类型(批量) + private static void handleFullReduce(JSONObject ruleObj, List newItems) { + JSONArray itemArray = ruleObj.getJSONObject("requirement") + .getJSONObject("buy") + .getJSONArray("item"); + + // 获取现有商品ID集合用于去重 + Set existingItems = new HashSet<>(); + for (int i = 0; i < itemArray.length(); i++) { + existingItems.add(itemArray.getInt(i)); + } + + // 添加新商品ID(去重) + for (JSONObject item : newItems) { + int itemId = item.getInt("item_id"); + if (!existingItems.contains(itemId)) { + itemArray.put(itemId); + existingItems.add(itemId); + } + } + } + + // 处理折扣类型(批量) + private static void handleDiscount(JSONObject ruleObj, List newItems) { + JSONArray discountArray = ruleObj.getJSONArray("discount"); + + // 创建索引用于快速查找 + Set existingIds = new HashSet<>(); + for (int i = 0; i < discountArray.length(); i++) { + existingIds.add(discountArray.getJSONObject(i).getString("item_id")); + } + + // 添加新商品(去重) + for (JSONObject item : newItems) { + String itemId = item.getString("item_id"); + + // 检查是否已存在相同商品 + boolean exists = existingIds.contains(itemId); + + // 如果存在则更新,否则添加 + if (exists) { + // 更新现有商品折扣率 + for (int i = 0; i < discountArray.length(); i++) { + JSONObject discountItem = discountArray.getJSONObject(i); + if (discountItem.getString("item_id").equals(itemId)) { + discountItem.put("rate", item.getString("rate")); + break; + } + } + } else { + // 添加新商品 + JSONObject discountItem = new JSONObject(); + discountItem.put("item_id", itemId); + discountItem.put("rate", item.getString("rate")); + discountArray.put(discountItem); + existingIds.add(itemId); + } + } + } + + // 处理秒杀类型(批量) + private static void handleSeckill(JSONObject ruleObj, List newItems) { + JSONArray discountArray = ruleObj.getJSONArray("discount"); + + // 创建索引用于快速查找 + Set existingIds = new HashSet<>(); + for (int i = 0; i < discountArray.length(); i++) { + existingIds.add(discountArray.getJSONObject(i).getInt("item_id")); + } + + // 添加新商品(去重) + for (JSONObject item : newItems) { + int itemId = item.getInt("item_id"); + + // 检查是否已存在相同商品 + boolean exists = existingIds.contains(itemId); + + // 如果存在则更新,否则添加 + if (exists) { + // 更新现有商品价格 + for (int i = 0; i < discountArray.length(); i++) { + JSONObject seckillItem = discountArray.getJSONObject(i); + if (seckillItem.getInt("item_id") == itemId) { + seckillItem.put("price", item.getInt("price")); + break; + } + } + } else { + // 添加新商品 + JSONObject seckillItem = new JSONObject(); + seckillItem.put("item_id", itemId); + seckillItem.put("price", item.getInt("price")); + discountArray.put(seckillItem); + existingIds.add(itemId); + } + } + } + + public static void main(String[] args) { + // 示例使用 + String dbRule = ""; // 模拟从数据库读取的规则字符串 + + // 创建折扣商品列表 + JSONObject discountItem1 = new JSONObject().put("item_id", "24839").put("rate", "15"); + JSONObject discountItem2 = new JSONObject().put("item_id", "24840").put("rate", "20"); + List discountItems = Arrays.asList(discountItem1, discountItem2); + + // 构建折扣规则 + String discountResult = buildPromotionRule("discount", dbRule, discountItems); + System.out.println("折扣结果:\n" + discountResult); + + // 创建满减商品列表 + JSONObject fullReduceItem1 = new JSONObject().put("item_id", 24915); + JSONObject fullReduceItem2 = new JSONObject().put("item_id", 24916); + List fullReduceItems = Arrays.asList(fullReduceItem1, fullReduceItem2); + + // 构建满减规则 + String fullReduceResult = buildPromotionRule("fullReduce", "", fullReduceItems); + System.out.println("\n满减结果:\n" + fullReduceResult); + + // 创建秒杀商品列表 + JSONObject seckillItem1 = new JSONObject().put("item_id", 24850).put("price", 8); + JSONObject seckillItem2 = new JSONObject().put("item_id", 24851).put("price", 12); + List seckillItems = Arrays.asList(seckillItem1, seckillItem2); + + // 构建秒杀规则 + String seckillResult = buildPromotionRule("seckill", null, seckillItems); + System.out.println("\n秒杀结果:\n" + seckillResult); + } + +}