From f2024d5be5d1b0866c9ae54b185d071228b3416a Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 27 Jan 2026 14:16:25 +0800 Subject: [PATCH 01/20] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=20=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E4=BF=AE=E6=94=B9=20=E5=88=86=E4=BA=AB=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=20=E8=BD=AE=E6=92=AD=E5=9B=BE=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/ACarouselController.java | 61 ++++++++++ .../admin/AShareBaseController.java | 47 ++++++++ .../controller/user/UCarouselController.java | 38 ++++++ .../admin/MiniAppPagesController.java | 2 +- .../com/czg/market/dto/MkCarouselDTO.java | 46 ++++++++ .../com/czg/market/entity/MkCarousel.java | 97 ++++++++++++++++ .../com/czg/market/entity/MkShareBase.java | 108 ++++++++++++++++++ .../czg/market/service/MkCarouselService.java | 19 +++ .../market/service/MkShareBaseService.java | 15 +++ .../market/mapper/MkCarouselMapper.java | 14 +++ .../market/mapper/MkShareBaseMapper.java | 14 +++ .../service/impl/MkCarouselServiceImpl.java | 46 ++++++++ .../service/impl/MkShareBaseServiceImpl.java | 43 +++++++ .../resources/mapper/MkCarouselMapper.xml | 7 ++ .../resources/mapper/MkShareBaseMapper.xml | 7 ++ .../service/impl/MiniAppPagesServiceImpl.java | 5 +- 16 files changed, 566 insertions(+), 3 deletions(-) create mode 100644 cash-api/market-server/src/main/java/com/czg/controller/admin/ACarouselController.java create mode 100644 cash-api/market-server/src/main/java/com/czg/controller/admin/AShareBaseController.java create mode 100644 cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/dto/MkCarouselDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkCarousel.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/service/MkCarouselService.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkCarouselMapper.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkShareBaseMapper.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java create mode 100644 cash-service/market-service/src/main/resources/mapper/MkCarouselMapper.xml create mode 100644 cash-service/market-service/src/main/resources/mapper/MkShareBaseMapper.xml diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/ACarouselController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/ACarouselController.java new file mode 100644 index 000000000..6e4dc48fe --- /dev/null +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/ACarouselController.java @@ -0,0 +1,61 @@ +package com.czg.controller.admin; + +import com.czg.annotation.SaAdminCheckPermission; +import com.czg.market.dto.MkCarouselDTO; +import com.czg.market.entity.MkCarousel; +import com.czg.market.service.MkCarouselService; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 轮播图配置 + * + * @author ww + */ +@RestController +@RequestMapping("/admin/carousel") +public class ACarouselController { + + @Resource + private MkCarouselService mkCarouselService; + + /** + * 轮播图配置 + */ + @GetMapping + @SaAdminCheckPermission(parentName = "轮播图配置", value = "carousel:config", name = "轮播图-列表") + public CzgResult> getCarousels(MkCarouselDTO carouselDTO) { + carouselDTO.setShopId(StpKit.USER.getShopId()); + return CzgResult.success(mkCarouselService.getCarousels(carouselDTO)); + } + + /** + * 轮播图配置:新增/修改 + */ + @PostMapping + @SaAdminCheckPermission(parentName = "轮播图配置", value = "carousel:up", name = "轮播图-新增/修改") + public CzgResult editCarousel(@RequestBody @Validated MkCarousel carousel) { + carousel.setShopId(StpKit.USER.getShopId()); + if (carousel.getId() == null) { + return CzgResult.success(mkCarouselService.save(carousel)); + } else { + return CzgResult.success(mkCarouselService.updateById(carousel, false)); + } + } + + /** + * 轮播图配置:删除 + */ + @DeleteMapping("/{id}") + @SaAdminCheckPermission(parentName = "轮播图配置", value = "carousel:up", name = "轮播图-新增/修改") + public CzgResult deleteCarousel(@PathVariable("id") Long id) { + return CzgResult.success(mkCarouselService.remove(QueryWrapper.create().eq(MkCarousel::getId, id).eq(MkCarousel::getShopId, StpKit.USER.getShopId()))); + } +} \ No newline at end of file diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/AShareBaseController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/AShareBaseController.java new file mode 100644 index 000000000..6d10b3d3e --- /dev/null +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/AShareBaseController.java @@ -0,0 +1,47 @@ +package com.czg.controller.admin; + +import com.czg.annotation.SaAdminCheckPermission; +import com.czg.market.entity.MkShareBase; +import com.czg.market.service.MkShareBaseService; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + + +/** + * 分享奖励基础 + * + * @author ww + */ +@RestController +@RequestMapping("/admin/shareBase") +public class AShareBaseController { + + @Resource + private MkShareBaseService mkShareBaseService; + + /** + * 分享奖励基础 + */ + @GetMapping + @SaAdminCheckPermission(parentName = "分享奖励基础", value = "share:config", name = "分享-配置") + public CzgResult getShareBase() { + return CzgResult.success(mkShareBaseService.getShareBase(StpKit.USER.getShopId())); + } + + /** + * 分享奖励基础:新增/修改 + */ + @PostMapping + @SaAdminCheckPermission(parentName = "分享奖励基础", value = "share:up", name = "分享-新增/修改") + public CzgResult editShareBase(@RequestBody MkShareBase shareBase) { + shareBase.setShopId(StpKit.USER.getShopId()); + MkShareBase share = mkShareBaseService.getById(shareBase.getShopId()); + if (share == null) { + return CzgResult.success(mkShareBaseService.save(shareBase)); + } else { + return CzgResult.success(mkShareBaseService.updateById(shareBase, false)); + } + } +} \ No newline at end of file diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java new file mode 100644 index 000000000..6f3a65c28 --- /dev/null +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java @@ -0,0 +1,38 @@ +package com.czg.controller.user; + +import com.czg.annotation.SaAdminCheckPermission; +import com.czg.market.dto.MkCarouselDTO; +import com.czg.market.entity.MkCarousel; +import com.czg.market.service.MkCarouselService; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + + +/** + * 轮播图配置 + * + * @author ww + */ +@RestController +@RequestMapping("/user/carousel") +public class UCarouselController { + + @Resource + private MkCarouselService mkCarouselService; + + /** + * 轮播图配置 + */ + @GetMapping + @SaAdminCheckPermission(parentName = "轮播图配置", value = "carousel:config", name = "轮播图-列表") + public CzgResult> getCarousels(MkCarouselDTO carouselDTO) { + carouselDTO.setShopId(StpKit.USER.getShopId()); + return CzgResult.success(mkCarouselService.getCarousels(carouselDTO)); + } +} \ No newline at end of file diff --git a/cash-api/system-server/src/main/java/com/czg/controller/admin/MiniAppPagesController.java b/cash-api/system-server/src/main/java/com/czg/controller/admin/MiniAppPagesController.java index 84faf8b88..6e44e502b 100644 --- a/cash-api/system-server/src/main/java/com/czg/controller/admin/MiniAppPagesController.java +++ b/cash-api/system-server/src/main/java/com/czg/controller/admin/MiniAppPagesController.java @@ -58,7 +58,7 @@ public class MiniAppPagesController { * @param status 小程序页面状态 -1 查全部 1 启用 0 禁用 */ @GetMapping("page") - @SaAdminCheckPermission(parentName = "小程序页面",value = "miniAppPages:page", name = "小程序页面分页") +// @SaAdminCheckPermission(parentName = "小程序页面",value = "miniAppPages:page", name = "小程序页面分页") public CzgResult> getMiniAppPage(String name, String path, Integer status) { return miniAppPageService.getMiniAppPage(name, path, status); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/dto/MkCarouselDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/MkCarouselDTO.java new file mode 100644 index 000000000..213d00b58 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/MkCarouselDTO.java @@ -0,0 +1,46 @@ + +package com.czg.market.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 轮播图配置表 实体类。 + * + * @author ww + * @since 2026-01-27 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class MkCarouselDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺Id + */ + private Long shopId; + + /** + * 轮播图名称(20字内) + */ + private String name; + + /** + * 是否可分享 1=开启 0=关闭 + */ + private Integer isShareable; + + /** + * 启用状态 1=启用 0=禁用 + */ + private Integer isEnabled; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkCarousel.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkCarousel.java new file mode 100644 index 000000000..41fdfcf89 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkCarousel.java @@ -0,0 +1,97 @@ +package com.czg.market.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 轮播图配置表 实体类。 + * + * @author ww + * @since 2026-01-27 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("mk_carousel") +public class MkCarousel implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @Id(keyType = KeyType.Auto) + private BigInteger id; + + /** + * 店铺Id + */ + private Long shopId; + + /** + * 轮播图名称(20字内) + */ + private String name; + + /** + * 轮播图片地址 + */ + private String imageUrl; + + /** + * 是否可分享 1=开启 0=关闭 + */ + private Integer isShareable; + + /** + * 跳转页面 tb_mini_app_pages的 id + */ + private Long jumpPageId; + /** + * 跳转页面路径 + */ + @Column(ignore = true) + private String jumpPagePath; + + /** + * 扩展参数 + */ + private String extendParam; + + /** + * 排序值,值越大越靠前 + */ + private Integer sort; + + /** + * 启用状态 1=启用 0=禁用 + */ + private Integer isEnabled; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java new file mode 100644 index 000000000..893f85d8d --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java @@ -0,0 +1,108 @@ +package com.czg.market.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 分享奖励基础配置 实体类。 + * + * @author ww + * @since 2026-01-27 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("mk_share_base") +public class MkShareBase implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺id + */ + @Id + private Long shopId; + + /** + * 功能开启状态 1=开启 0=关闭 + */ + private Integer isEnabled; + + /** + * 可获得奖励的分享页面,用逗号分隔, + * 店铺首页 index + * 我的 dine + * 点餐页 eat + * 点餐页 eat-detail + * 套餐推广-列表 pp-list + * 套餐推广-详情 pp-detail + * 商品拼团-列表 gb-list + * 商品拼团-详情 gb-detail + * 全民股东 dis + */ + private String rewardSharePages; + + /** + * 分享人奖励的优惠券ID,关联优惠券表 + */ + private Long sharerCouponId; + /** + * 分享人奖励的优惠券名称 + */ + @Column(ignore = true) + private String sharerCouponName; + + /** + * 分享人单次获得优惠券数量 + */ + private Integer sharerCouponNum; + + /** + * 可获得奖励次数 1=仅1次 2=每次分享成功 + */ + private Integer rewardTimesType; + + /** + * 被分享人奖励的优惠券ID,关联优惠券表(可选) + */ + private Long sharedUserCouponId; + /** + * 被分享人奖励的优惠券名称 + */ + @Column(ignore = true) + private String sharedUserCouponName; + + /** + * 被分享人单次获得优惠券数量(可选) + */ + private Integer sharedUserCouponNum; + + /** + * 被分享人弹窗开关 1=开启 0=关闭 + */ + private Integer isSharedUserPopup; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkCarouselService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkCarouselService.java new file mode 100644 index 000000000..06beaec24 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkCarouselService.java @@ -0,0 +1,19 @@ +package com.czg.market.service; + +import com.czg.market.dto.MkCarouselDTO; +import com.mybatisflex.core.service.IService; +import com.czg.market.entity.MkCarousel; + +import java.util.List; + +/** + * 轮播图配置表 服务层。 + * + * @author ww + * @since 2026-01-27 + */ +public interface MkCarouselService extends IService { + + List getCarousels(MkCarouselDTO mkCarouselDTO); + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java new file mode 100644 index 000000000..36d0b8636 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java @@ -0,0 +1,15 @@ +package com.czg.market.service; + +import com.mybatisflex.core.service.IService; +import com.czg.market.entity.MkShareBase; + +/** + * 分享奖励基础配置 服务层。 + * + * @author ww + * @since 2026-01-27 + */ +public interface MkShareBaseService extends IService { + + MkShareBase getShareBase(Long shopId); +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkCarouselMapper.java b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkCarouselMapper.java new file mode 100644 index 000000000..53c41e46e --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkCarouselMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.market.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.market.entity.MkCarousel; + +/** + * 轮播图配置表 映射层。 + * + * @author ww + * @since 2026-01-27 + */ +public interface MkCarouselMapper extends BaseMapper { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkShareBaseMapper.java b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkShareBaseMapper.java new file mode 100644 index 000000000..57b2b5a9c --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkShareBaseMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.market.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.market.entity.MkShareBase; + +/** + * 分享奖励基础配置 映射层。 + * + * @author ww + * @since 2026-01-27 + */ +public interface MkShareBaseMapper extends BaseMapper { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java new file mode 100644 index 000000000..a660ce30d --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java @@ -0,0 +1,46 @@ +package com.czg.service.market.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.czg.market.dto.MkCarouselDTO; +import com.czg.system.entity.MiniAppPages; +import com.czg.system.service.MiniAppPageService; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.market.entity.MkCarousel; +import com.czg.market.service.MkCarouselService; +import com.czg.service.market.mapper.MkCarouselMapper; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 轮播图配置表 服务层实现。 + * + * @author ww + * @since 2026-01-27 + */ +@Service +public class MkCarouselServiceImpl extends ServiceImpl implements MkCarouselService { + @DubboReference + private MiniAppPageService miniAppPageService; + + @Override + public List getCarousels(MkCarouselDTO mkCarouselDTO) { + QueryWrapper queryWrapper = query().eq(MkCarousel::getShopId, mkCarouselDTO.getShopId()) + .eq(MkCarousel::getIsEnabled, mkCarouselDTO.getIsEnabled()) + .eq(MkCarousel::getIsShareable, mkCarouselDTO.getIsShareable()) + .orderBy(MkCarousel::getSort, false); + if (StrUtil.isNotBlank(mkCarouselDTO.getName())) { + queryWrapper.like(MkCarousel::getName, mkCarouselDTO.getName()); + } + List list = list(queryWrapper); + list.forEach(mkCarousel -> { + MiniAppPages miniAppPages = miniAppPageService.getById(mkCarousel.getJumpPageId()); + if (miniAppPages != null) { + mkCarousel.setJumpPagePath(miniAppPages.getPath()); + } + }); + return list; + } +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java new file mode 100644 index 000000000..e9230d092 --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java @@ -0,0 +1,43 @@ +package com.czg.service.market.service.impl; + +import com.czg.market.dto.ShopCouponDTO; +import com.czg.market.service.ShopCouponService; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.market.entity.MkShareBase; +import com.czg.market.service.MkShareBaseService; +import com.czg.service.market.mapper.MkShareBaseMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +/** + * 分享奖励基础配置 服务层实现。 + * + * @author ww + * @since 2026-01-27 + */ +@Service +public class MkShareBaseServiceImpl extends ServiceImpl implements MkShareBaseService { + + @Resource + private ShopCouponService shopCouponService; + + @Override + public MkShareBase getShareBase(Long shopId) { + MkShareBase shareBase = getById(shopId); + if (shareBase != null) { + if (shareBase.getSharerCouponId() != null) { + ShopCouponDTO sharerCoupon = shopCouponService.getCouponById(shareBase.getSharerCouponId()); + if (sharerCoupon != null) { + shareBase.setSharerCouponName(sharerCoupon.getTitle()); + } + } + if (shareBase.getSharedUserCouponId() != null) { + ShopCouponDTO shareUserCoupon = shopCouponService.getCouponById(shareBase.getSharedUserCouponId()); + if (shareUserCoupon != null) { + shareBase.setSharedUserCouponName(shareUserCoupon.getTitle()); + } + } + } + return shareBase; + } +} diff --git a/cash-service/market-service/src/main/resources/mapper/MkCarouselMapper.xml b/cash-service/market-service/src/main/resources/mapper/MkCarouselMapper.xml new file mode 100644 index 000000000..ebac91f72 --- /dev/null +++ b/cash-service/market-service/src/main/resources/mapper/MkCarouselMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/market-service/src/main/resources/mapper/MkShareBaseMapper.xml b/cash-service/market-service/src/main/resources/mapper/MkShareBaseMapper.xml new file mode 100644 index 000000000..4a29cba9a --- /dev/null +++ b/cash-service/market-service/src/main/resources/mapper/MkShareBaseMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/MiniAppPagesServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/MiniAppPagesServiceImpl.java index eaa892387..673969d60 100644 --- a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/MiniAppPagesServiceImpl.java +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/MiniAppPagesServiceImpl.java @@ -12,7 +12,7 @@ import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; import com.czg.service.system.mapper.MiniAppPagesMapper; -import org.springframework.stereotype.Service; +import org.apache.dubbo.config.annotation.DubboService; /** * 小程序页面路径 服务层实现。 @@ -20,7 +20,7 @@ import org.springframework.stereotype.Service; * @author mac * @since 2025-02-12 */ -@Service +@DubboService public class MiniAppPagesServiceImpl extends ServiceImpl implements MiniAppPageService { @Override @@ -46,6 +46,7 @@ public class MiniAppPagesServiceImpl extends ServiceImpl Date: Tue, 27 Jan 2026 16:22:56 +0800 Subject: [PATCH 02/20] =?UTF-8?q?=E5=88=86=E4=BA=AB=20=E9=A2=86=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/user/UCarouselController.java | 37 ++++++-- .../user/UDistributionController.java | 28 ------ .../service/MkDistributionUserService.java | 9 ++ .../market/service/MkShareBaseService.java | 2 + .../impl/MkDistributionUserServiceImpl.java | 86 +++++++++++++++++++ .../service/impl/MkShareBaseServiceImpl.java | 84 ++++++++++++++++++ 6 files changed, 211 insertions(+), 35 deletions(-) diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java index 6f3a65c28..ba27d78e1 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java @@ -1,15 +1,13 @@ package com.czg.controller.user; -import com.czg.annotation.SaAdminCheckPermission; import com.czg.market.dto.MkCarouselDTO; import com.czg.market.entity.MkCarousel; import com.czg.market.service.MkCarouselService; +import com.czg.market.service.MkShareBaseService; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import jakarta.annotation.Resource; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -20,19 +18,44 @@ import java.util.List; * @author ww */ @RestController -@RequestMapping("/user/carousel") +@RequestMapping("/user") public class UCarouselController { @Resource private MkCarouselService mkCarouselService; + @Resource + private MkShareBaseService mkShareBaseService; + + /** * 轮播图配置 */ - @GetMapping - @SaAdminCheckPermission(parentName = "轮播图配置", value = "carousel:config", name = "轮播图-列表") + @GetMapping("/carousel") public CzgResult> getCarousels(MkCarouselDTO carouselDTO) { carouselDTO.setShopId(StpKit.USER.getShopId()); return CzgResult.success(mkCarouselService.getCarousels(carouselDTO)); } + + /** + * 分享 领取触发 + * + * @param tagType + * @param shopId + * @param fromUserId 分享人的shopUserId + * @param toUserId 被分享人的shopUserId + */ + public record ShareClaim(String tagType, Long shopId, Long fromUserId, Long toUserId) { + } + + + /** + * 分享 领取触发 + * 会绑定上下级关系 + */ + @PostMapping("/shareClaim") + public CzgResult shareClaim(@RequestBody ShareClaim shareClaim) { + mkShareBaseService.shareClaim(shareClaim.tagType, shareClaim.shopId, shareClaim.fromUserId, shareClaim.toUserId); + return CzgResult.success(); + } } \ No newline at end of file diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java index 7d5b1c4c7..5c9d09df4 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java @@ -19,7 +19,6 @@ import com.mybatisflex.core.paginate.Page; import io.seata.core.exception.TransactionException; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.core.NestedExceptionUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -107,19 +106,6 @@ public class UDistributionController { return CzgResult.success(distributionUserService.getInviteCode(shopId, shopUserId)); } - /** - * 分销员中心-获取邀请码 - */ - @GetMapping("/autoGetInviteCode") - public CzgResult autoGetInviteCode(@RequestParam Long shopId, @RequestParam Long shopUserId) { - try { - return CzgResult.success(distributionUserService.getInviteCode(shopId, shopUserId)); - } catch (Exception e) { - String rootMsg = NestedExceptionUtils.getMostSpecificCause(e).getMessage(); - log.error("获取邀请码失败用户:{},:{}", shopUserId, rootMsg); - return CzgResult.success(""); - } - } /** * 分销员中心-实名认证 @@ -133,20 +119,6 @@ public class UDistributionController { return CzgResult.success(); } - /** - * 分销员中心-无感-绑定邀请人 - */ - @PostMapping("/autoBindInviteUser") - public CzgResult> autoBindInviteUser(@RequestBody MkDistributionUserDTO param) throws TransactionException { - try { - bindInviteUser(param); - } catch (Exception e) { - log.error("无感绑定邀请人失败:{}", param, e); - } - return CzgResult.success(); - } - - /** * 分销员中心-绑定邀请人 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionUserService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionUserService.java index 6afc074f5..908fe49ec 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionUserService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionUserService.java @@ -60,9 +60,18 @@ public interface MkDistributionUserService extends IService /** * 分销员中心-绑定邀请人 + * 通过邀请码 */ void bindInviteUser(MkDistributionUserDTO param) throws CzgException, ValidateException; + + /** + * 分销员中心-绑定邀请人 + * 通过邀请人id + * @param fromUserId shopUserId 邀请人 + * @param toUserId 被邀请人邀请人 + */ + void bindInviteUser(Long fromUserId, Long toUserId, Long shopId) throws CzgException, ValidateException; /** * 获取分销员分页列表 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java index 36d0b8636..f214c51b0 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShareBaseService.java @@ -12,4 +12,6 @@ import com.czg.market.entity.MkShareBase; public interface MkShareBaseService extends IService { MkShareBase getShareBase(Long shopId); + + void shareClaim(String tagType, Long shopId, Long fromUserId, Long toUserId); } diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java index 098617e46..7dfaef760 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java @@ -311,6 +311,92 @@ public class MkDistributionUserServiceImpl extends ServiceImpl= mkDistributionConfig.getInviteCount()) { + ShopUser parentShopUser1 = new ShopUser(); + parentShopUser1.setId(parentShopUser.getId()); + parentShopUser1.upDistributionShop(shopId, 1); + shopUserService.updateById(parentShopUser1); + } + } + if (mkDistributionConfig != null && !"not_upgrade".equals(mkDistributionConfig.getUpgradeType()) && parent.getIsAssignLevel() == 0) { + if ("invite".equals(mkDistributionConfig.getUpgradeType())) { + if (mkDistributionConfig.getInviteConsume() == 1) { + long count = orderInfoService.count(QueryWrapper.create() + .eq(OrderInfo::getUserId, shopUser.getUserId()) + .eq(OrderInfo::getShopId, parent.getShopId()) + .eq(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode())); + if (count < 1) { + throw new CzgException("绑定失败,被邀请人需要成功支付一笔订单"); + } + } + MkDistributionLevelConfig levelConfig = levelConfigService.getOne(QueryWrapper.create() + .eq(MkDistributionLevelConfig::getShopId, parent.getShopId()) + .le(MkDistributionLevelConfig::getInviteCount, newDistributionUser.getInviteCount()) + .orderBy(MkDistributionLevelConfig::getId).desc().limit(1)); + if (levelConfig != null) { + newDistributionUser.setDistributionLevelId(levelConfig.getId()); + newDistributionUser.setDistributionLevelName(levelConfig.getName()); + newDistributionUser.setStatus(1); + } + } else if ("cost".equals(mkDistributionConfig.getUpgradeType())) { + costUpgradeLevel(parent.getId(), parent.getShopId()); + } + } + update(newDistributionUser, QueryWrapper.create().eq(MkDistributionUser::getId, parent.getId()) + .eq(MkDistributionUser::getShopId, parent.getShopId())); + } + @Override public void costUpgradeLevelBefore(Long userId, Long shopId) { ShopUser shopUser = shopUserService.getShopUserInfo(shopId, userId); diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java index e9230d092..f27b7f769 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java @@ -1,7 +1,13 @@ package com.czg.service.market.service.impl; +import cn.hutool.core.util.StrUtil; +import com.czg.market.dto.MkShopCouponGiftDTO; import com.czg.market.dto.ShopCouponDTO; +import com.czg.market.entity.MkShopCouponRecord; +import com.czg.market.service.MkDistributionUserService; +import com.czg.market.service.MkShopCouponRecordService; import com.czg.market.service.ShopCouponService; +import com.czg.utils.FunUtils; import com.mybatisflex.spring.service.impl.ServiceImpl; import com.czg.market.entity.MkShareBase; import com.czg.market.service.MkShareBaseService; @@ -20,6 +26,10 @@ public class MkShareBaseServiceImpl extends ServiceImpl distributionUserService.bindInviteUser(fromUserId, toUserId, shopId)); + } + MkShareBase shareBase = getById(shopId); + if (shareBase == null || shareBase.getIsEnabled().equals(1) || StrUtil.isBlank(shareBase.getRewardSharePages())) { + return; + } + if (!shareBase.getRewardSharePages().contains(tagType)) { + return; + } + FunUtils.safeRun(() -> { + //发放分享人优惠券 + if (shareBase.getSharerCouponId() != null) { + boolean grant = true; + if (shareBase.getRewardTimesType().equals(1)) { + boolean exists = mkShopCouponRecordService.exists(query() + .eq(MkShopCouponRecord::getShopId, shopId) + .eq(MkShopCouponRecord::getShopUserId, fromUserId) + .eq(MkShopCouponRecord::getSource, "邀请获得")); + grant = !exists; + } + if (grant) { + MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO(); + giftDTO.setShopId(shopId) + .setSourceId(shareBase.getShopId()) + .setSourceFlowId(toUserId) + .setShopUserId(fromUserId) + .setCouponId(shareBase.getSharerCouponId()) + .setSource("邀请获得"); + int receiveNum = 1; + if (shareBase.getSharerCouponNum() != null && shareBase.getSharerCouponNum() > 0) { + receiveNum = shareBase.getSharerCouponNum(); + } + mkShopCouponRecordService.receiveCoupon(giftDTO, receiveNum, false); + } + } + return null; + }, "邀请人获取优惠券"); + FunUtils.safeRun(() -> { + //发放被分享人优惠券 + if (shareBase.getSharedUserCouponId() != null) { + boolean exists = mkShopCouponRecordService.exists(query() + .eq(MkShopCouponRecord::getShopId, shopId) + .eq(MkShopCouponRecord::getShopUserId, toUserId) + .eq(MkShopCouponRecord::getSourceFlowId, fromUserId) + .eq(MkShopCouponRecord::getSource, "参与分享获得")); + if (!exists) { + MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO(); + giftDTO.setShopId(shopId) + .setSourceId(shareBase.getShopId()) + .setShopUserId(toUserId) + .setSourceFlowId(fromUserId) + .setCouponId(shareBase.getSharedUserCouponId()) + .setSource("参与分享获得"); + int receiveNum = 1; + if (shareBase.getSharedUserCouponNum() != null && shareBase.getSharedUserCouponNum() > 0) { + receiveNum = shareBase.getSharedUserCouponNum(); + } + mkShopCouponRecordService.receiveCoupon(giftDTO, receiveNum, false); + } + } + return null; + }, "被分享人获取优惠券"); + } } From ae67fb6f8e8beaa9071c1721f1c583e4badeac18 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 27 Jan 2026 17:03:08 +0800 Subject: [PATCH 03/20] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=20=E8=8E=B7=E5=8F=96to?= =?UTF-8?q?ken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/account/util/AcAccountUtil.java | 37 ++++++++---------- .../account/util/WechatMiniMsgUtil.java | 28 +++++++------ .../market/service/impl/AppWxServiceImpl.java | 39 +++++++------------ .../market/service/impl/WxServiceImpl.java | 39 ++++++------------- .../service/product/util/WxAccountUtil.java | 28 +++++++------ 5 files changed, 69 insertions(+), 102 deletions(-) diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/util/AcAccountUtil.java b/cash-service/account-service/src/main/java/com/czg/service/account/util/AcAccountUtil.java index 6cad3e069..63a4f1c63 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/util/AcAccountUtil.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/util/AcAccountUtil.java @@ -1,17 +1,13 @@ package com.czg.service.account.util; -import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONObject; import com.czg.constants.ParamCodeCst; -import com.czg.service.RedisService; import com.czg.system.service.SysParamsService; -import jakarta.annotation.Resource; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.util.LinkedHashMap; @@ -26,9 +22,7 @@ import java.util.Map; @Slf4j @Component public class AcAccountUtil { - @Resource - @Lazy - private RedisService redisService; + @DubboReference private SysParamsService paramsService; @@ -54,7 +48,7 @@ public class AcAccountUtil { String accessToken = getAccessToken(); // String accessToken = "97_HZVThQrtvOiCZGrr23ZHN0cVpHBJHc18RSFHU6dvkQDMAme4GsG0NU-Dax1HP5Wx-aGa1l35KaqiMVv61TCj0Qk8DK1LC6kQ8uKLDfgRYVJjX3QjcelmIjp4PCkERBeABAUHR"; if (StrUtil.isBlank(accessToken)) { - log.error("获取 access_token 失败"); + log.error("银收客czg 公众号获取 access_token 失败"); return ""; } String bodyJson = "{\"action_info\":{\"scene\":{\"scene_str\":\"" + userId + "\"}},\"action_name\":\"QR_STR_SCENE\",\"expire_seconds\":\"2592000\"}"; @@ -87,23 +81,24 @@ public class AcAccountUtil { public String getAccessToken() { - String accessToken = Convert.toStr(redisService.get("wx:ac:AccessToken")); - if (StrUtil.isNotEmpty(accessToken)) { - return accessToken; - } Map userAc = paramsService.getParamsByMap("user_ac_key_set", ParamCodeCst.USER_AC_KEY_SET); // 用户小程序参数 String acAppId = userAc.get(ParamCodeCst.Wechat.Ac.USER_WX_AC_APP_ID); String acSecrete = userAc.get(ParamCodeCst.Wechat.Ac.USER_WX_AC_SECRETE); - String resp = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", acAppId, acSecrete)); - JSONObject respInfo = JSONObject.parseObject(resp); - if (!respInfo.containsKey("access_token")) { - log.warn("公众号获取token失败, 响应内容: {}", resp); - return ""; + + String resp = HttpUtil.get(StrUtil.format("https://access-token.sxczgkj.com/accessToken?appId={}&appSecret={}", acAppId, acSecrete)); +// 响应 {"accessToken":"100_6C_jltHANT1y2Fot5PXKFDzPXTyWumCsao0oMoNRvJUTuxS0IOVO4nBmjdmx5dZfYItShFVSAKYzNDf7ZGLPlx52ii1Y1qerrbbSmIiLWCrec5qjBY4gV5Tfv8YKKTdABAEEN","appId":"wx212769170d2c6b2a"} + if (StrUtil.isNotBlank(resp)) { + JSONObject respInfo = JSONObject.parseObject(resp); + return respInfo.getString("accessToken"); + } else { + String resp2 = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", acAppId, acSecrete)); + JSONObject respInfo = JSONObject.parseObject(resp2); + if (!respInfo.containsKey("access_token")) { + log.warn("银收客czg 公众号获取token失败, 响应内容: {}", resp2); + return ""; + } + return respInfo.getString("access_token"); } - accessToken = respInfo.getString("access_token"); - int expiresIn = respInfo.getInteger("expires_in"); - redisService.set("wx:ac:AccessToken", accessToken, expiresIn - 10); - return accessToken; } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatMiniMsgUtil.java b/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatMiniMsgUtil.java index 126229f04..956042aca 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatMiniMsgUtil.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatMiniMsgUtil.java @@ -1,7 +1,6 @@ package com.czg.service.account.util; import cn.hutool.core.codec.Base64; -import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.symmetric.AES; @@ -11,6 +10,7 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.czg.config.RedisCst; import com.czg.constants.ParamCodeCst; +import com.czg.exception.CzgException; import com.czg.resp.CzgResult; import com.czg.service.RedisService; import com.czg.system.dto.SysParamsDTO; @@ -140,7 +140,7 @@ public class WechatMiniMsgUtil { public String getAccountOpenId(String code) { Map shopAc = sysParamsService.getParamsByMap("shop_ac_key_set", ParamCodeCst.SHOP_AC_KEY_SET); - String accountAppId = shopAc.get(ParamCodeCst.Wechat.Ac.SHOP_WX_AC_APP_ID); + String accountAppId = shopAc.get(ParamCodeCst.Wechat.Ac.SHOP_WX_AC_APP_ID); String accountSecrete = shopAc.get(ParamCodeCst.Wechat.Ac.SHOP_WX_AC_SECRETE); String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?"; Map requestUrlParam = new HashMap<>(); @@ -162,25 +162,23 @@ public class WechatMiniMsgUtil { //获取小程序token private String getAccessToken() { - String accessToken = Convert.toStr(redisService.get("wx:mini:AccessToken")); - if (StrUtil.isNotEmpty(accessToken)) { - return accessToken; - } // 商户小程序参数 Map shopMiniKeyMap = sysParamsService.getParamsByMap("shop_mini_key_set", ParamCodeCst.SHOP_MINI_KEY_SET); String appId = shopMiniKeyMap.get(ParamCodeCst.Wechat.Mini.SHOP_WX_APP_ID); String secrete = shopMiniKeyMap.get(ParamCodeCst.Wechat.Mini.SHOP_WX_SECRETE); - String url = String.format("%s?grant_type=client_credential&appid=%s&secret=%s", TOKEN_URL, appId, secrete); - String response = HttpUtil.get(url); - JSONObject jsonResponse = JSONObject.parseObject(response); - if (!jsonResponse.containsKey("access_token")) { - throw new RuntimeException("Failed to retrieve access token: " + response); + String resp = HttpUtil.get(StrUtil.format("https://access-token.sxczgkj.com/accessToken?appId={}&appSecret={}", appId, secrete)); + if (StrUtil.isNotBlank(resp)) { + JSONObject respInfo = JSONObject.parseObject(resp); + return respInfo.getString("accessToken"); + } else { + String response = HttpUtil.get(String.format("%s?grant_type=client_credential&appid=%s&secret=%s", TOKEN_URL, appId, secrete)); + JSONObject jsonResponse = JSONObject.parseObject(response); + if (!jsonResponse.containsKey("access_token")) { + throw new CzgException("零点八零商户端 获取access_token失败: " + response); + } + return jsonResponse.getString("access_token"); } - accessToken = jsonResponse.getString("access_token"); - int expiresIn = jsonResponse.getInteger("expires_in"); - redisService.set("wx:mini:AccessToken", accessToken, expiresIn - 10); - return accessToken; } /** diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/AppWxServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/AppWxServiceImpl.java index c5037ba50..ec9581f72 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/AppWxServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/AppWxServiceImpl.java @@ -1,15 +1,14 @@ package com.czg.service.market.service.impl; +import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSONObject; import com.czg.constants.ParamCodeCst; import com.czg.exception.CzgException; -import com.czg.service.RedisService; import com.czg.system.service.SysParamsService; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -17,6 +16,7 @@ import java.util.Map; /** * 微信支付service + * * @author Administrator */ @Component @@ -27,35 +27,26 @@ public class AppWxServiceImpl extends BaseWx { @DubboReference private SysParamsService paramsService; - public AppWxServiceImpl(@Autowired RedisService autoRedisService) { - this.redisService = autoRedisService; + public AppWxServiceImpl() { config = new Config(); } @Override public String getAccessToken(boolean refresh) { init(); - Object token = redisService.get("wx:user:access_token"); - if (!refresh && token instanceof String) { - return (String) token; - } - String response = HttpUtil.get(WX_ACCESS_TOKEN_URL, - Map.of("grant_type", "client_credential", "appid", config.appId, "secret", config.appSecret) - ); - - log.info("获取access_token响应: {}", response); - JSONObject jsonObject = JSONObject.parseObject(response); - String accessToken = jsonObject.getString("access_token"); - if (accessToken == null) { - throw new RuntimeException("获取access_token失败"); + String resp = HttpUtil.get(StrUtil.format("https://access-token.sxczgkj.com/accessToken?appId={}&appSecret={}", config.appId, config.appSecret)); +// 响应 {"accessToken":"100_6C_jltHANT1y2Fot5PXKFDzPXTyWumCsao0oMoNRvJUTuxS0IOVO4nBmjdmx5dZfYItShFVSAKYzNDf7ZGLPlx52ii1Y1qerrbbSmIiLWCrec5qjBY4gV5Tfv8YKKTdABAEEN","appId":"wx212769170d2c6b2a"} + if (StrUtil.isNotBlank(resp)) { + JSONObject respInfo = JSONObject.parseObject(resp); + return respInfo.getString("accessToken"); + } else { + String response = HttpUtil.get(WX_ACCESS_TOKEN_URL, + Map.of("grant_type", "client_credential", "appid", config.appId, "secret", config.appSecret) + ); + JSONObject jsonObject = JSONObject.parseObject(response); + return jsonObject.getString("access_token"); } - Long expiresIn = jsonObject.getLong("expires_in"); - if (expiresIn == null) { - expiresIn = DEFAULT_EXPIRES_IN; - } - redisService.set("wx:user:access_token", accessToken, expiresIn - EXPIRES_OFFSET); - return accessToken; } @Override @@ -65,7 +56,7 @@ public class AppWxServiceImpl extends BaseWx { // 微信支付参数 Map payKeyMap = paramsService.getParamsByMap("pay_key_set", ParamCodeCst.PAY_KEY_SET); - + // 小程序id config.appId = userMiniKeyMap.get(ParamCodeCst.Wechat.Mini.USER_WX_APP_ID); // 小程序secrete diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/WxServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/WxServiceImpl.java index e637ed3c1..7df9f9076 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/WxServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/WxServiceImpl.java @@ -1,18 +1,16 @@ package com.czg.service.market.service.impl; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSONObject; import com.czg.constants.ParamCodeCst; -import com.czg.service.RedisService; import com.czg.system.service.SysParamsService; import com.ijpay.core.kit.RsaKit; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Map; -import java.util.Set; /** @@ -27,38 +25,25 @@ public class WxServiceImpl extends BaseWx { @DubboReference private SysParamsService paramsService; - private final Set shopMiniKeys = Set.of(ParamCodeCst.Wechat.Mini.SHOP_WX_APP_ID, ParamCodeCst.Wechat.Mini.SHOP_WX_SECRETE); - - - public WxServiceImpl(@Autowired RedisService redisService) { - this.redisService = redisService; + public WxServiceImpl() { config = new Config(); } @Override public String getAccessToken(boolean refresh) { init(); - Object token = redisService.get("wx:shop:access_token"); - if (!refresh && token instanceof String) { - return (String) token; - } - String response = HttpUtil.get(WX_ACCESS_TOKEN_URL, - Map.of("grant_type", "client_credential", "appid", config.appId, "secret", config.appSecret) - ); - - log.info("获取access_token响应: {}", response); - JSONObject jsonObject = JSONObject.parseObject(response); - String accessToken = jsonObject.getString("access_token"); - if (accessToken == null) { - throw new RuntimeException("获取access_token失败"); + String resp = HttpUtil.get(StrUtil.format("https://access-token.sxczgkj.com/accessToken?appId={}&appSecret={}", config.appId, config.appSecret)); + if (StrUtil.isNotBlank(resp)) { + JSONObject respInfo = JSONObject.parseObject(resp); + return respInfo.getString("accessToken"); + } else { + String response = HttpUtil.get(WX_ACCESS_TOKEN_URL, + Map.of("grant_type", "client_credential", "appid", config.appId, "secret", config.appSecret) + ); + JSONObject jsonObject = JSONObject.parseObject(response); + return jsonObject.getString("access_token"); } - Long expiresIn = jsonObject.getLong("expires_in"); - if (expiresIn == null) { - expiresIn = DEFAULT_EXPIRES_IN; - } - redisService.set("wx:shop:access_token", accessToken, expiresIn - EXPIRES_OFFSET); - return accessToken; } @Override diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/util/WxAccountUtil.java b/cash-service/product-service/src/main/java/com/czg/service/product/util/WxAccountUtil.java index a94e6bc3c..3c18e0c99 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/util/WxAccountUtil.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/util/WxAccountUtil.java @@ -7,12 +7,9 @@ import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONObject; import com.czg.exception.CzgException; -import com.czg.service.RedisService; -import jakarta.annotation.Resource; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.math.BigDecimal; @@ -41,9 +38,6 @@ public class WxAccountUtil { @Value("${wx.ysk.warnMsgTmpId}") private String warnMsgTmpId; - @Resource - @Lazy - private RedisService redisService; static LinkedHashMap linkedHashMap = new LinkedHashMap<>(); @@ -97,16 +91,20 @@ public class WxAccountUtil { } public String getAccessToken() { - String resp = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", appId, secrete)); - JSONObject respInfo = JSONObject.parseObject(resp); - if (!respInfo.containsKey("access_token")) { - log.warn("公众号获取token失败, 响应内容: {}", resp); - throw new RuntimeException(resp); + String resp = HttpUtil.get(StrUtil.format("https://access-token.sxczgkj.com/accessToken?appId={}&appSecret={}", appId, secrete)); +// 响应 {"accessToken":"100_6C_jltHANT1y2Fot5PXKFDzPXTyWumCsao0oMoNRvJUTuxS0IOVO4nBmjdmx5dZfYItShFVSAKYzNDf7ZGLPlx52ii1Y1qerrbbSmIiLWCrec5qjBY4gV5Tfv8YKKTdABAEEN","appId":"wx212769170d2c6b2a"} + if(StrUtil.isNotBlank(resp)){ + JSONObject respInfo = JSONObject.parseObject(resp); + return respInfo.getString("accessToken"); + }else { + String resp1 = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", appId, secrete)); + JSONObject respInfo = JSONObject.parseObject(resp1); + if (!respInfo.containsKey("access_token")) { + log.warn("银收客 公众号获取token失败, 响应内容: {}", resp1); + throw new CzgException(resp); + } + return respInfo.getString("access_token"); } - String accessToken = respInfo.getString("access_token"); -// int expiresIn = respInfo.getInteger("expires_in"); -// redisService.set("accessToken", accessToken, expiresIn - 10); - return accessToken; } public JSONObject sendTemplateMsg(String detail, String templateId, String toUserOpenId, Map data) { From 6cd6ac74ea0356463ef03cf90aea2c55b0733e65 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 28 Jan 2026 10:54:58 +0800 Subject: [PATCH 04/20] =?UTF-8?q?=E5=88=86=E9=94=80=E6=9B=B4=E5=90=8D=20?= =?UTF-8?q?=E5=85=A8=E6=B0=91=E8=82=A1=E4=B8=9C=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=85=A8=E6=B0=91=E8=82=A1=E4=B8=9C=E7=BE=A4=E8=81=8A=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/ADisGroupController.java | 47 +++++++++++++ .../user/UDistributionController.java | 34 +++++++--- .../controller/admin/ProductController.java | 25 ++++--- .../market/entity/MkDistributionGroup.java | 67 +++++++++++++++++++ .../czg/market/entity/MkDistributionUser.java | 5 +- .../service/MkDistributionGroupService.java | 14 ++++ .../mapper/MkDistributionGroupMapper.java | 14 ++++ .../impl/MkDistributionGroupServiceImpl.java | 18 +++++ .../impl/MkDistributionUserServiceImpl.java | 8 ++- .../mapper/MkDistributionGroupMapper.xml | 7 ++ .../service/impl/ProductServiceImpl.java | 4 +- 11 files changed, 219 insertions(+), 24 deletions(-) create mode 100644 cash-api/market-server/src/main/java/com/czg/controller/admin/ADisGroupController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionGroup.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionGroupService.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkDistributionGroupMapper.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionGroupServiceImpl.java create mode 100644 cash-service/market-service/src/main/resources/mapper/MkDistributionGroupMapper.xml diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/ADisGroupController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/ADisGroupController.java new file mode 100644 index 000000000..212c6dcef --- /dev/null +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/ADisGroupController.java @@ -0,0 +1,47 @@ +package com.czg.controller.admin; + +import com.czg.annotation.SaAdminCheckPermission; +import com.czg.market.entity.MkDistributionGroup; +import com.czg.market.service.MkDistributionGroupService; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + + +/** + * 全民股东群聊 + * + * @author ww + */ +@RestController +@RequestMapping("/admin/disGroup") +public class ADisGroupController { + + @Resource + private MkDistributionGroupService mkDistributionGroupService; + + /** + * 全民股东群聊 + */ + @GetMapping + @SaAdminCheckPermission(parentName = "全民股东群聊", value = "share:config", name = "全民股东群聊-配置") + public CzgResult getShareBase() { + return CzgResult.success(mkDistributionGroupService.getById(StpKit.USER.getShopId())); + } + + /** + * 全民股东群聊:新增/修改 + */ + @PostMapping + @SaAdminCheckPermission(parentName = "全民股东群聊", value = "share:up", name = "全民股东群聊-新增/修改") + public CzgResult editShareBase(@RequestBody MkDistributionGroup group) { + group.setShopId(StpKit.USER.getShopId()); + MkDistributionGroup share = mkDistributionGroupService.getById(group.getShopId()); + if (share == null) { + return CzgResult.success(mkDistributionGroupService.save(group)); + } else { + return CzgResult.success(mkDistributionGroupService.updateById(group, false)); + } + } +} \ No newline at end of file diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java index 5c9d09df4..3294306ee 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UDistributionController.java @@ -3,6 +3,7 @@ package com.czg.controller.user; import com.czg.account.entity.UserInfo; import com.czg.market.dto.MkDistributionUserDTO; import com.czg.market.dto.MkDistributionWithdrawFlowDTO; +import com.czg.market.entity.MkDistributionUser; import com.czg.market.entity.MkDistributionWithdrawFlow; import com.czg.market.service.MkDistributionConfigService; import com.czg.market.service.MkDistributionFlowService; @@ -16,7 +17,7 @@ import com.czg.sa.StpKit; import com.czg.task.DistributionTask; import com.czg.utils.AssertUtil; import com.mybatisflex.core.paginate.Page; -import io.seata.core.exception.TransactionException; +import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; @@ -25,7 +26,7 @@ import org.springframework.web.bind.annotation.*; import java.util.Map; /** - * 分销相关 + * 全民股东相关 * * @author Administrator */ @@ -59,7 +60,7 @@ public class UDistributionController { /** - * 分销员中心-获取配置 + * 全民股东=-获取配置 */ @GetMapping("/getConfig") public CzgResult getConfig(@RequestParam Long shopId) { @@ -67,7 +68,7 @@ public class UDistributionController { } /** - * 分销员中心-首页 + * 全民股东-首页 */ @PostMapping("/centerUser") public CzgResult> centerUser() { @@ -75,7 +76,7 @@ public class UDistributionController { } /** - * 分销员中心-已开通的店铺 + * 全民股东界-已开通的店铺 */ @GetMapping("/centerUser/activates") public CzgResult> activates(@RequestParam(required = false, defaultValue = "1") Integer page, @RequestParam(required = false, defaultValue = "10") Integer size) { @@ -83,7 +84,7 @@ public class UDistributionController { } /** - * 分销员中心-未开通的店铺 + * 全民股东-未开通的店铺 */ @GetMapping("/centerUser/unActivates") public CzgResult> unActivates(@RequestParam(required = false, defaultValue = "1") Integer page, @RequestParam(required = false, defaultValue = "10") Integer size) { @@ -91,7 +92,7 @@ public class UDistributionController { } /** - * 分销员中心-配置信息 + * 全民股东-配置信息 */ @GetMapping("/centerConfig") public CzgResult> centerConfig(@RequestParam Long shopId) { @@ -99,7 +100,18 @@ public class UDistributionController { } /** - * 分销员中心-获取邀请码 + * 全民股东界面-进入过标识 + */ + @GetMapping("/editIn") + public CzgResult editIn(@RequestParam Long shopUserId) { + MkDistributionUser distributionUser = new MkDistributionUser(); + distributionUser.setFirstIn(1); + distributionUserService.update(distributionUser, QueryWrapper.create().eq(MkDistributionUser::getId, shopUserId)); + return CzgResult.success(); + } + + /** + * 全民股东-获取邀请码 */ @GetMapping("/getInviteCode") public CzgResult getInviteCode(@RequestParam Long shopId, @RequestParam Long shopUserId) { @@ -108,7 +120,7 @@ public class UDistributionController { /** - * 分销员中心-实名认证 + * 全民股东-实名认证 */ @PostMapping("/realNameAuth") public CzgResult> realNameAuth(@RequestBody UserInfo userInfo) { @@ -120,7 +132,7 @@ public class UDistributionController { } /** - * 分销员中心-绑定邀请人 + * 全民股东-绑定邀请人 */ @PostMapping("/bindInviteUser") public CzgResult> bindInviteUser(@RequestBody MkDistributionUserDTO param) { @@ -132,7 +144,7 @@ public class UDistributionController { } /** - * 分销员:获取邀请人分页列表 + * 全民股东:获取邀请人分页列表 */ @GetMapping("/inviteUser") public CzgResult> getInviteUser( diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java index 628edb9be..85bab5667 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java @@ -2,6 +2,7 @@ package com.czg.controller.admin; import cn.hutool.core.convert.Convert; import cn.hutool.core.thread.ThreadUtil; +import com.alibaba.fastjson2.JSONObject; import com.czg.account.entity.ShopInfo; import com.czg.account.service.ShopInfoService; import com.czg.config.RabbitPublisher; @@ -30,6 +31,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; /** @@ -66,9 +68,16 @@ public class ProductController { @GetMapping("page") @OperationLog("商品-分页") //@SaAdminCheckPermission("product:page") - public CzgResult> getProductPage(ProductDTO param) { + public CzgResult> getProductPage(ProductDTO param) { Page data = productService.getProductPage(param); - return CzgResult.success(data); + Map map = JSONObject.parseObject(JSONObject.toJSONString(data), Map.class); + if(data.getRecords() != null){ + ProductDTO first = data.getRecords().getFirst(); + map.put("warnLine", first.getWarnLine()); + }else { + map.put("warnLine", 0); + } + return CzgResult.success(map); } /** @@ -111,7 +120,7 @@ public class ProductController { for (ProdSkuDTO prodSkuDTO : dto.getSkuList()) { ValidatorUtil.validateEntity(prodSkuDTO, DefaultGroup.class); } - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); dto.setShopId(shopId); productService.addProduct(dto); asyncProductToShop(dto.getId()); @@ -140,7 +149,7 @@ public class ProductController { if (dto.getStockNumber() != null) { StpKit.USER.checkStaffPermission("yun_xu_xiu_gai_shang_pin_ku_cun"); } - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); dto.setShopId(shopId); productService.updateProduct(dto); asyncProductToShop(dto.getId()); @@ -155,7 +164,7 @@ public class ProductController { //@SaStaffCheckPermission("yun_xu_xiu_gai_shang_pin") public CzgResult updateProductStock(@RequestBody ProductModifyStockParam param) { ValidatorUtil.validateEntity(param, DefaultGroup.class); - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); param.setShopId(shopId); productService.updateProductStock(param); ThreadUtil.execAsync(() -> { @@ -176,7 +185,7 @@ public class ProductController { public CzgResult deleteProduct(@PathVariable("id") Long id) { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); productService.deleteProduct(shopId, id); asyncProductToShop(id); ThreadUtil.execAsync(() -> { @@ -193,7 +202,7 @@ public class ProductController { //@SaStaffCheckPermission("yun_xu_shang_xia_jia_shang_pin") //@SaAdminCheckPermission("product:on-off") public CzgResult onOffProduct(@RequestBody @Validated({DefaultGroup.class}) ProductIsSaleParam param) { - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); param.setShopId(shopId); productService.onOffProduct(param); ThreadUtil.execAsync(() -> { @@ -210,7 +219,7 @@ public class ProductController { //@SaStaffCheckPermission("yun_xu_shou_qing_shang_pin") //@SaAdminCheckPermission("product:markIsSoldOut") public CzgResult markIsSoldOutProduct(@RequestBody @Validated({DefaultGroup.class}) ProductIsSoldOutParam param) { - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); param.setShopId(shopId); productService.markProductIsSoldOut(param); ThreadUtil.execAsync(() -> { diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionGroup.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionGroup.java new file mode 100644 index 000000000..226dab36d --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionGroup.java @@ -0,0 +1,67 @@ +package com.czg.market.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 分销员管理群(全民股东管理) 实体类。 + * + * @author ww + * @since 2026-01-28 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("mk_distribution_group") +public class MkDistributionGroup implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Id + private Long shopId; + + /** + * 群二维码地址 + */ + private String groupUrl; + + /** + * 模块标题 15字以内 + */ + private String title; + + /** + * 模块内容 20字以内 + */ + private String content; + + /** + * 是否开启 + */ + private Integer isEnable; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionUser.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionUser.java index c7950afca..f739c3d2a 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionUser.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkDistributionUser.java @@ -1,7 +1,6 @@ package com.czg.market.entity; import com.mybatisflex.annotation.Id; -import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.Table; import lombok.AllArgsConstructor; import lombok.Builder; @@ -117,5 +116,9 @@ public class MkDistributionUser implements Serializable { * 邀请码 */ private String inviteCode; + /** + * 是否第一次进入全民股东界面 + */ + private Integer firstIn; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionGroupService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionGroupService.java new file mode 100644 index 000000000..bbfdd0cd2 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkDistributionGroupService.java @@ -0,0 +1,14 @@ +package com.czg.market.service; + +import com.mybatisflex.core.service.IService; +import com.czg.market.entity.MkDistributionGroup; + +/** + * 分销员管理群(全民股东管理) 服务层。 + * + * @author ww + * @since 2026-01-28 + */ +public interface MkDistributionGroupService extends IService { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkDistributionGroupMapper.java b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkDistributionGroupMapper.java new file mode 100644 index 000000000..3461cb49e --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/MkDistributionGroupMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.market.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.market.entity.MkDistributionGroup; + +/** + * 分销员管理群(全民股东管理) 映射层。 + * + * @author ww + * @since 2026-01-28 + */ +public interface MkDistributionGroupMapper extends BaseMapper { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionGroupServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionGroupServiceImpl.java new file mode 100644 index 000000000..2143aa9c8 --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionGroupServiceImpl.java @@ -0,0 +1,18 @@ +package com.czg.service.market.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.market.entity.MkDistributionGroup; +import com.czg.market.service.MkDistributionGroupService; +import com.czg.service.market.mapper.MkDistributionGroupMapper; +import org.springframework.stereotype.Service; + +/** + * 分销员管理群(全民股东管理) 服务层实现。 + * + * @author ww + * @since 2026-01-28 + */ +@Service +public class MkDistributionGroupServiceImpl extends ServiceImpl implements MkDistributionGroupService{ + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java index 7dfaef760..b9e2953fa 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java @@ -61,6 +61,8 @@ import java.util.stream.Collectors; @Service public class MkDistributionUserServiceImpl extends ServiceImpl implements MkDistributionUserService { + @Resource + private MkDistributionGroupService mkDistributionGroupService; @Resource private MkDistributionConfigService mkDistributionConfigService; @Resource @@ -156,6 +158,9 @@ public class MkDistributionUserServiceImpl extends ServiceImpl distributionUser = new HashMap<>(); distributionUser.put("distributionId", mkDistributionUser.getId()); @@ -165,6 +170,7 @@ public class MkDistributionUserServiceImpl extends ServiceImpl levelConfigList = mkDistributionConfigVO.getLevelConfigList(); @@ -186,8 +192,6 @@ public class MkDistributionUserServiceImpl extends ServiceImpl + + + + diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java index 751400229..3d85750b7 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java @@ -668,7 +668,7 @@ public class ProductServiceImpl extends ServiceImpl impl @Override public void stockWarning(Integer warnLine) { - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); UpdateChain.of(Product.class) .set(Product::getWarnLine, warnLine) .eq(Product::getShopId, shopId) @@ -678,7 +678,7 @@ public class ProductServiceImpl extends ServiceImpl impl @Override @Transactional(rollbackFor = Exception.class) public void reportDamage(ProductReportDamageParam param) { - Long shopId = StpKit.USER.getShopId(0L); + Long shopId = StpKit.USER.getShopId(); Long createUserId = StpKit.USER.getLoginIdAsLong(); String createUserName = StpKit.USER.getAccount(); Product product = mapper.selectOneById(param.getProductId()); From 25b9a5b38993e43b5cfd51a734c9a370fb6853e0 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 28 Jan 2026 11:40:29 +0800 Subject: [PATCH 05/20] =?UTF-8?q?=E5=88=86=E9=94=80=E5=91=98=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/controller/admin/DistributionUserController.java | 2 ++ .../market/service/impl/MkDistributionUserServiceImpl.java | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/DistributionUserController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/DistributionUserController.java index 6d54f29bd..e442bbe42 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/admin/DistributionUserController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/DistributionUserController.java @@ -1,5 +1,6 @@ package com.czg.controller.admin; +import com.czg.annotation.Debounce; import com.czg.annotation.SaAdminCheckPermission; import com.czg.log.annotation.OperationLog; import com.czg.market.dto.MkDistributionUserDTO; @@ -57,6 +58,7 @@ public class DistributionUserController { * * @return 是否成功 */ + @Debounce @PostMapping @OperationLog("分销员-添加") @SaAdminCheckPermission(parentName = "分销相关",value = "distribution:user:add", name = "分销员添加") diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java index b9e2953fa..774f8feb0 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkDistributionUserServiceImpl.java @@ -467,8 +467,10 @@ public class MkDistributionUserServiceImpl extends ServiceImpl shopUser)); + List shopUserList = shopUserService.list(QueryWrapper.create().in(ShopUser::getId, shopUserIds)); + if (CollUtil.isNotEmpty(shopUserList)) { + shopUserMap = shopUserList.stream().collect(Collectors.toMap(ShopUser::getId, shopUser -> shopUser)); + } } for (MkDistributionUserDTO record : page.getRecords()) { ShopUser shopUser = shopUserMap.get(record.getId()); From 9e2cf024eb46146aac71f3b937628288779d7a41 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Wed, 28 Jan 2026 13:47:33 +0800 Subject: [PATCH 06/20] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/ShopUserController.java | 5 + .../czg/account/dto/shopuser/ShopUserDTO.java | 1 - .../dto/shopuser/ShopUserExportDTO.java | 116 ++++++++ .../czg/account/service/AShopUserService.java | 3 + cash-common/cash-common-tools/pom.xml | 5 + .../main/java/com/czg/excel/DataSupplier.java | 21 ++ .../java/com/czg/excel/ExcelExportConfig.java | 40 +++ .../java/com/czg/excel/ExcelExportUtil.java | 247 ++++++++++++++++++ cash-dependencies/pom.xml | 7 + .../src/main/java/com/czg/EntryManager.java | 4 +- .../third/alipay/AlipayIsvEntryManager.java | 44 +++- .../service/impl/AShopUserServiceImpl.java | 22 ++ 12 files changed, 506 insertions(+), 9 deletions(-) create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserExportDTO.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/excel/DataSupplier.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportConfig.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java index ae561f0ac..68f81cf7d 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java @@ -97,6 +97,11 @@ public class ShopUserController { return CzgResult.success(shopUserService.getPage(key, isVip, amount)); } + @GetMapping("/export") + public void exportUserList(String key, Integer isVip, HttpServletResponse response) { + shopUserService.exportUserList(key, isVip, response); + } + @GetMapping("/getPage") public CzgResult> getPage(@RequestParam(required = false)String key,@RequestParam(required = false) Integer isVip) { return CzgResult.success(shopUserService.getPage(key, isVip)); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserDTO.java index d81826f51..aca7b9f10 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserDTO.java @@ -28,5 +28,4 @@ public class ShopUserDTO extends ShopUser { private String nextMemberLevelName; private Long nextExperience; private Long pointBalance; - private boolean isNew; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserExportDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserExportDTO.java new file mode 100644 index 000000000..b3a99931d --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopuser/ShopUserExportDTO.java @@ -0,0 +1,116 @@ +package com.czg.account.dto.shopuser; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author yjjie + * @date 2026/1/28 11:30 + */ +@Data +public class ShopUserExportDTO { + + @ExcelProperty("手机号") + private String phone; + + @ExcelProperty("会员生日") + private String birthDay; + + @ExcelProperty("用户昵称") + private String nickName; + + @ExcelIgnore + private Integer status; + @ExcelProperty("会员状态") + private String statusRemark; + + @ExcelIgnore + private Integer isVip; + @ExcelProperty("是否会员") + private String vipRemark; + + @ExcelProperty("会员编号") + private String code; + + @ExcelProperty("余额") + private BigDecimal amount; + + @ExcelProperty("充值次数") + private Integer rechargeCount; + + @ExcelProperty("消费累计") + private BigDecimal consumeAmount; + + @ExcelProperty("消费次数") + private Integer consumeCount; + + @ExcelProperty("经验值") + private Long experience; + + @ExcelIgnore + private String distributionShops; + @ExcelProperty("是否分销员") + private String distributionShopsRemark; + + @ExcelProperty("优惠券数量") + private Long couponNum; + + @ExcelProperty("订单数量") + private Long orderNumber; + + @ExcelProperty("充值金额") + private BigDecimal rechargeAmount; + + @ExcelProperty("会员等级") + private String memberLevelName; + + @ExcelProperty("下一级会员等级") + private String nextMemberLevelName; + + @ExcelProperty("升级所需经验值") + private Long nextExperience; + + @ExcelProperty("积分余额") + private Long pointBalance; + + @ExcelProperty("加入会员时间") + private LocalDateTime joinTime; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + public String getVipRemark() { + if (isVip == null || isVip == 0) { + return "否"; + } + return "是"; + } + + public String getStatusRemark() { + if (status == null || status == 0) { + return "禁用"; + } + return "正常"; + } + + public String getDistributionShopsRemark() { + if (StrUtil.isBlank(distributionShops) || !distributionShops.contains("_")) { + return "否"; + } + + String[] split = distributionShops.split("_"); + if (split.length < 2) { + return "否"; + } + if ("0".equals(split[1])) { + return "否"; + } + + return "是"; + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/AShopUserService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/AShopUserService.java index fedebbd0c..905d43540 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/AShopUserService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/AShopUserService.java @@ -4,6 +4,7 @@ import com.czg.account.dto.shopuser.*; import com.czg.account.entity.ShopUser; import com.czg.market.entity.SmsPushEventUser; import com.mybatisflex.core.paginate.Page; +import jakarta.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.util.List; @@ -22,6 +23,8 @@ public interface AShopUserService { Page getPushEventUser(SmsPushEventUser smsPushEventUser); Page getAcPushEventUser(SmsPushEventUser smsPushEventUser); + void exportUserList(String key, Integer isVip, HttpServletResponse response); + Boolean add(Long shopId, ShopUserAddDTO shopUserAddDTO); diff --git a/cash-common/cash-common-tools/pom.xml b/cash-common/cash-common-tools/pom.xml index ccbce27f9..dd578f7da 100644 --- a/cash-common/cash-common-tools/pom.xml +++ b/cash-common/cash-common-tools/pom.xml @@ -95,6 +95,11 @@ mybatis-flex-processor provided + + + com.alibaba + easyexcel + diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/DataSupplier.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/DataSupplier.java new file mode 100644 index 000000000..68779d324 --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/DataSupplier.java @@ -0,0 +1,21 @@ +package com.czg.excel; + +import java.util.List; + +/** + * 数据提供者接口(用于分批获取数据) + * @author yjjie + * @date 2026/1/28 10:51 + */ +@FunctionalInterface +public interface DataSupplier { + + /** + * 获取指定页的数据 + * + * @param pageNum 页码 + * @param pageSize 每页大小 + * @return 数据列表 + */ + List getData(int pageNum, int pageSize); +} diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportConfig.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportConfig.java new file mode 100644 index 000000000..186cd00af --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportConfig.java @@ -0,0 +1,40 @@ +package com.czg.excel; + +import lombok.Data; + +/** + * Excel导出配置类 + * @author yjjie + * @date 2026/1/28 10:47 + */ +@Data +public class ExcelExportConfig { + + /** + * 默认工作表名称 + */ + private String defaultSheetName = "Sheet1"; + + /** + * 默认文件名 + */ + private String defaultFileName = "export_data"; + + /** + * 是否自动关闭流 + */ + private boolean autoCloseStream = true; + + /** + * 响应头编码 + */ + private String charset = "UTF-8"; + + public ExcelExportConfig() {} + + public ExcelExportConfig(String defaultSheetName, String defaultFileName) { + this.defaultSheetName = defaultSheetName; + this.defaultFileName = defaultFileName; + } + +} diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java new file mode 100644 index 000000000..ba1d6d570 --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java @@ -0,0 +1,247 @@ +package com.czg.excel; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import com.czg.exception.CzgException; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.List; + +/** + * EasyExcel导出工具类 + * @author yjjie + * @date 2026/1/28 10:48 + */ +@Slf4j +public class ExcelExportUtil { + + private static final ExcelExportConfig DEFAULT_CONFIG = new ExcelExportConfig(); + + /** + * 导出Excel到HttpServletResponse + * + * @param data 数据列表 + * @param clazz 数据类型 + * @param fileName 文件名(不含扩展名) + * @param response HttpServletResponse + * @param 数据类型 + */ + public static void exportToResponse(List data, Class clazz, + String fileName, HttpServletResponse response) { + exportToResponse(data, clazz, fileName, DEFAULT_CONFIG, response); + } + + /** + * 导出Excel到HttpServletResponse(自定义配置) + * + * @param data 数据列表 + * @param clazz 数据类型 + * @param fileName 文件名(不含扩展名) + * @param config 配置信息 + * @param response HttpServletResponse + * @param 数据类型 + */ + public static void exportToResponse(List data, Class clazz, + String fileName, ExcelExportConfig config, + HttpServletResponse response) { + if (data == null) { + data = Collections.emptyList(); + } + + setResponseHeader(response, fileName, config); + + try (OutputStream outputStream = response.getOutputStream()) { + ExcelWriter excelWriter = EasyExcel.write(outputStream, clazz) + .autoCloseStream(config.isAutoCloseStream()) + .build(); + + WriteSheet writeSheet = EasyExcel.writerSheet(config.getDefaultSheetName()).build(); + excelWriter.write(data, writeSheet); + excelWriter.finish(); + + log.info("Excel导出成功,文件名:{},数据量:{}", fileName, data.size()); + } catch (IOException e) { + log.error("Excel导出失败", e); + throw new CzgException("Excel导出失败", e); + } + } + + /** + * 导出Excel到文件 + * + * @param data 数据列表 + * @param clazz 数据类型 + * @param filePath 文件路径 + * @param 数据类型 + */ + public static void exportToFile(List data, Class clazz, String filePath) { + exportToFile(data, clazz, filePath, DEFAULT_CONFIG); + } + + /** + * 导出Excel到文件(自定义配置) + * + * @param data 数据列表 + * @param clazz 数据类型 + * @param filePath 文件路径 + * @param config 配置信息 + * @param 数据类型 + */ + public static void exportToFile(List data, Class clazz, + String filePath, ExcelExportConfig config) { + if (data == null) { + data = Collections.emptyList(); + } + + try { + EasyExcel.write(filePath, clazz) + .sheet(config.getDefaultSheetName()) + .doWrite(data); + log.info("Excel文件导出成功,路径:{},数据量:{}", filePath, data.size()); + } catch (Exception e) { + log.error("Excel文件导出失败", e); + throw new CzgException("Excel文件导出失败", e); + } + } + + /** + * 带样式的Excel导出到Response + * + * @param data 数据列表 + * @param clazz 数据类型 + * @param fileName 文件名 + * @param response HttpServletResponse + * @param 数据类型 + */ + public static void exportWithStyleToResponse(List data, Class clazz, + String fileName, HttpServletResponse response) { + if (data == null) { + data = Collections.emptyList(); + } + + setResponseHeader(response, fileName, DEFAULT_CONFIG); + + try (OutputStream outputStream = response.getOutputStream()) { + // 设置表格样式 + HorizontalCellStyleStrategy styleStrategy = createCellStyleStrategy(); + + ExcelWriter excelWriter = EasyExcel.write(outputStream, clazz) + .registerWriteHandler(styleStrategy) + .autoCloseStream(true) + .build(); + + WriteSheet writeSheet = EasyExcel.writerSheet(DEFAULT_CONFIG.getDefaultSheetName()).build(); + excelWriter.write(data, writeSheet); + excelWriter.finish(); + + log.info("带样式Excel导出成功,文件名:{},数据量:{}", fileName, data.size()); + } catch (IOException e) { + log.error("带样式Excel导出失败", e); + throw new CzgException("Excel导出失败", e); + } + } + + /** + * 大数据量分批导出(避免内存溢出) + * + * @param dataSupplier 数据提供者(分页获取数据) + * @param clazz 数据类型 + * @param fileName 文件名 + * @param response HttpServletResponse + * @param batchSize 每批大小 + * @param 数据类型 + */ + public static void exportBigDataToResponse(DataSupplier dataSupplier, + Class clazz, String fileName, + HttpServletResponse response, int batchSize) { + setResponseHeader(response, fileName, DEFAULT_CONFIG); + + try (OutputStream outputStream = response.getOutputStream()) { + ExcelWriter excelWriter = EasyExcel.write(outputStream, clazz) + .autoCloseStream(true) + .build(); + + WriteSheet writeSheet = EasyExcel.writerSheet(DEFAULT_CONFIG.getDefaultSheetName()).build(); + + int pageNum = 1; + List batchData; + boolean hasNext = true; + + while (hasNext) { + batchData = dataSupplier.getData(pageNum, batchSize); + if (batchData != null && !batchData.isEmpty()) { + excelWriter.write(batchData, writeSheet); + pageNum++; + } else { + hasNext = false; + } + } + + excelWriter.finish(); + log.info("大数据量Excel导出成功,文件名:{},总页数:{}", fileName, pageNum - 1); + } catch (IOException e) { + log.error("大数据量Excel导出失败", e); + throw new CzgException("Excel导出失败", e); + } + } + + /** + * 设置响应头 + */ + private static void setResponseHeader(HttpServletResponse response, String fileName, ExcelExportConfig config) { + try { + String encodedFileName = URLEncoder.encode(fileName, config.getCharset()) + .replaceAll("\\+", "%20"); + String contentDisposition = "attachment;filename*=utf-8''" + encodedFileName + ".xlsx"; + + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding(config.getCharset()); + response.setHeader("Content-Disposition", contentDisposition); + } catch (Exception e) { + log.warn("设置响应头失败", e); + } + } + + /** + * 创建表格样式策略 + */ + private static HorizontalCellStyleStrategy createCellStyleStrategy() { + // 表头样式 + WriteCellStyle headStyle = new WriteCellStyle(); + headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + headStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + // 内容样式 + WriteCellStyle contentStyle = new WriteCellStyle(); + contentStyle.setHorizontalAlignment(HorizontalAlignment.LEFT); + contentStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + return new HorizontalCellStyleStrategy(headStyle, contentStyle); + } + + /** + * 获取数据总行数(用于前端显示进度) + */ + public static int getDataCount(Class clazz) { + Field[] fields = clazz.getDeclaredFields(); + int count = 0; + for (Field field : fields) { + if (field.isAnnotationPresent(ExcelProperty.class)) { + count++; + } + } + return count; + } +} diff --git a/cash-dependencies/pom.xml b/cash-dependencies/pom.xml index a598172c8..3622a95df 100644 --- a/cash-dependencies/pom.xml +++ b/cash-dependencies/pom.xml @@ -44,6 +44,7 @@ 4.1.128.Final 0.2.17 3.1.65.ALL + 4.0.3 @@ -282,6 +283,12 @@ alipay-sdk-java-v3 ${apipay-v3.version} + + + com.alibaba + easyexcel + ${easyexcel.version} + diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index 5ba69d428..c7df7b292 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -384,8 +384,8 @@ public class EntryManager { // verifyEntryParam(merchantDto); // uploadParamImage(merchantDto); //// System.out.println(merchantDto); - EntryRespDto respDto = entryMerchant(merchantDto, PayCst.Type.WECHAT); -// entryMerchant(merchantDto, PayCst.Type.ALIPAY); +// EntryRespDto respDto = entryMerchant(merchantDto, PayCst.Type.WECHAT); + EntryRespDto respDto = entryMerchant(merchantDto, PayCst.Type.ALIPAY); // entryMerchant(merchantDto, PayCst.Type.WECHAT, PayCst.Type.ALIPAY); System.out.println(respDto); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java index 87b0b5fa3..d0ac6e2ab 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java @@ -1,5 +1,6 @@ package com.czg.third.alipay; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONObject; import com.alipay.v3.ApiException; import com.alipay.v3.api.*; @@ -110,7 +111,10 @@ public class AlipayIsvEntryManager { respDto.setEntryId(batchNo); AlipayOpenAgentFacetofaceSignModel signModel = buildFaceToFaceModel(reqDto, batchNo); - File businessLicensePic = UploadFileUtil.getFileByUrl(reqDto.getBusinessLicenceInfo().getLicensePic().getUrl()); + File businessLicensePic = null; + if (reqDto.getBusinessLicenceInfo() != null && reqDto.getBusinessLicenceInfo().getLicensePic() != null && StrUtil.isNotBlank(reqDto.getBusinessLicenceInfo().getLicensePic().getUrl())) { + businessLicensePic = UploadFileUtil.getFileByUrl(reqDto.getBusinessLicenceInfo().getLicensePic().getUrl()); + } File shopScenePic = UploadFileUtil.getFileByUrl(reqDto.getStoreInfo().getInsidePic().getUrl()); File shopSignBoardPic = UploadFileUtil.getFileByUrl(reqDto.getStoreInfo().getDoorPic().getUrl()); @@ -237,10 +241,12 @@ public class AlipayIsvEntryManager { signModel.setRate("0.38"); signModel.setSignAndAuth(true); - signModel.setBusinessLicenseNo(licenceInfo.getLicenceNo()); - signModel.setBusinessLicenseMobile(legalPersonInfo.getLegalPersonPhone()); - signModel.setLongTerm(PayCst.LONG_TERM_DATE.equals(licenceInfo.getLicenceEndDate())); - signModel.setDateLimitation(licenceInfo.getLicenceStartDate()); + if (licenceInfo != null) { + signModel.setBusinessLicenseNo(licenceInfo.getLicenceNo()); + signModel.setBusinessLicenseMobile(legalPersonInfo.getLegalPersonPhone()); + signModel.setLongTerm(PayCst.LONG_TERM_DATE.equals(licenceInfo.getLicenceEndDate())); + signModel.setDateLimitation(licenceInfo.getLicenceStartDate()); + } signModel.setShopName(baseInfo.getShortName()); @@ -258,6 +264,32 @@ public class AlipayIsvEntryManager { public static void main(String[] args) { // confirmRequest("2026010815384505500018243"); - queryMerchantBatchStatus(null, "2026010815384505500018243"); + queryMerchantBatchStatus(null, "2026012310512107600067177"); + +// AggregateMerchantDto merchantDto = new AggregateMerchantDto(); +// merchantDto.setMerchantCode("CZG20260112151202099"); +// +// MerchantBaseInfoDto baseInfoDto = new MerchantBaseInfoDto(); +// baseInfoDto.setUserType("3"); +// baseInfoDto.setShortName("巩奕杰_商户"); +// baseInfoDto.setMccCode("A0001_B0199"); +// baseInfoDto.setAlipayAccount("15596653310"); +// baseInfoDto.setContactPersonType("SUPER"); +// baseInfoDto.setContactName("巩奕杰"); +// baseInfoDto.setCertType("0"); +// baseInfoDto.setContactPhone("15596653310"); +// baseInfoDto.setContactEmail("sankejuzi@163.com"); +// merchantDto.setMerchantBaseInfo(baseInfoDto); +// +// StoreInfoDto storeInfoDto = new StoreInfoDto(); +// storeInfoDto.setBusinessAddress("陕西省西安市浐灞欧亚国际"); +// storeInfoDto.setMercAreaCode("610113"); +// storeInfoDto.setMercProvCode("610000"); +// storeInfoDto.setMercCityCode("610100"); +// storeInfoDto.setDoorPic(new ImageDto().setUrl("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/2c207c6f4a764ad18e501ed10fbfad59.png")); +// storeInfoDto.setInsidePic(new ImageDto().setUrl("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/394b4834698a47e9b75419a5fd7f7de7.jpg")); +// merchantDto.setStoreInfo(storeInfoDto); +// +// entryMerchant(null, merchantDto); } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java index 1c9da9464..159b344c2 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java @@ -3,6 +3,7 @@ package com.czg.service.account.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; import com.czg.account.dto.shopuser.*; import com.czg.account.entity.ShopUser; import com.czg.account.entity.UserInfo; @@ -10,6 +11,7 @@ import com.czg.account.service.AShopUserService; import com.czg.account.service.ShopInfoService; import com.czg.account.service.ShopUserService; import com.czg.account.service.UserInfoService; +import com.czg.excel.ExcelExportUtil; import com.czg.exception.CzgException; import com.czg.market.entity.MemberLevelConfig; import com.czg.market.entity.MkShopCouponRecord; @@ -28,12 +30,14 @@ import com.github.pagehelper.PageInfo; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; @@ -124,6 +128,24 @@ public class AShopUserServiceImpl implements AShopUserService { } } + @Override + public void exportUserList(String key, Integer isVip, HttpServletResponse response) { + Long mainIdByShopId = shopInfoService.getMainIdByShopId(StpKit.USER.getShopId()); + PageHelper.startPage(PageUtil.buildPageHelp()); + List dtoList = shopUserMapper.selectPageByKeyAndIsVip(mainIdByShopId, isVip, key, null); + + // 将 dtoList 转换为 ShopUserExportDTO 列表 + List exportList = new ArrayList<>(); + for (ShopUserDTO shopUserDTO : dtoList) { + ShopUserExportDTO exportDTO = BeanUtil.copyProperties(shopUserDTO, ShopUserExportDTO.class); + exportDTO.setVipRemark((isVip != null && isVip.equals(1)) ? "是" : "否"); + exportList.add(exportDTO); + } + + log.info(JSONObject.toJSONString(exportList)); + ExcelExportUtil.exportToResponse(exportList, ShopUserExportDTO.class, "店铺用户列表.xlsx", response); + } + @Override public Boolean updateInfo(Long shopId, ShopUserEditDTO shopUserEditDTO) { From c984867e4ec50251409896010f07793da79654e0 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Wed, 28 Jan 2026 13:57:30 +0800 Subject: [PATCH 07/20] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=8E=A5=E5=8F=A31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/controller/admin/ShopUserController.java | 6 ++++++ .../service/impl/AShopUserServiceImpl.java | 15 ++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java index 68f81cf7d..e8e9daae5 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java @@ -97,6 +97,12 @@ public class ShopUserController { return CzgResult.success(shopUserService.getPage(key, isVip, amount)); } + /** + * 导出用户列表 + * + * @param key 昵称或手机号 + * @param isVip 0 非vip 1 vip + */ @GetMapping("/export") public void exportUserList(String key, Integer isVip, HttpServletResponse response) { shopUserService.exportUserList(key, isVip, response); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java index 159b344c2..e70795843 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AShopUserServiceImpl.java @@ -3,8 +3,8 @@ package com.czg.service.account.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson2.JSONObject; import com.czg.account.dto.shopuser.*; +import com.czg.account.entity.ShopInfo; import com.czg.account.entity.ShopUser; import com.czg.account.entity.UserInfo; import com.czg.account.service.AShopUserService; @@ -37,7 +37,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.ArrayList; import java.util.List; @@ -131,19 +130,13 @@ public class AShopUserServiceImpl implements AShopUserService { @Override public void exportUserList(String key, Integer isVip, HttpServletResponse response) { Long mainIdByShopId = shopInfoService.getMainIdByShopId(StpKit.USER.getShopId()); + ShopInfo shopInfo = shopInfoService.getById(StpKit.USER.getShopId()); PageHelper.startPage(PageUtil.buildPageHelp()); List dtoList = shopUserMapper.selectPageByKeyAndIsVip(mainIdByShopId, isVip, key, null); // 将 dtoList 转换为 ShopUserExportDTO 列表 - List exportList = new ArrayList<>(); - for (ShopUserDTO shopUserDTO : dtoList) { - ShopUserExportDTO exportDTO = BeanUtil.copyProperties(shopUserDTO, ShopUserExportDTO.class); - exportDTO.setVipRemark((isVip != null && isVip.equals(1)) ? "是" : "否"); - exportList.add(exportDTO); - } - - log.info(JSONObject.toJSONString(exportList)); - ExcelExportUtil.exportToResponse(exportList, ShopUserExportDTO.class, "店铺用户列表.xlsx", response); + List exportList = BeanUtil.copyToList(dtoList, ShopUserExportDTO.class); + ExcelExportUtil.exportToResponse(exportList, ShopUserExportDTO.class, shopInfo == null ? "店铺用户列表" : shopInfo.getShopName() + "_用户列表", response); } From e3887148c1d11c6d5d4c5eba0e83819127668445 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 28 Jan 2026 14:39:55 +0800 Subject: [PATCH 08/20] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AB=AF=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=88=86=E4=BA=AB=E7=9A=84=E5=9F=BA=E7=A1=80=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/controller/user/UCarouselController.java | 8 ++++++++ .../src/main/java/com/czg/market/entity/MkShareBase.java | 6 ++++++ .../market/service/impl/MkShareBaseServiceImpl.java | 1 + 3 files changed, 15 insertions(+) diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java index ba27d78e1..242f22a54 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java @@ -2,6 +2,7 @@ package com.czg.controller.user; import com.czg.market.dto.MkCarouselDTO; import com.czg.market.entity.MkCarousel; +import com.czg.market.entity.MkShareBase; import com.czg.market.service.MkCarouselService; import com.czg.market.service.MkShareBaseService; import com.czg.resp.CzgResult; @@ -48,6 +49,13 @@ public class UCarouselController { public record ShareClaim(String tagType, Long shopId, Long fromUserId, Long toUserId) { } + /** + * 分享 基础配置 + */ + @PostMapping("/share") + public CzgResult share(@RequestParam Long shopId) { + return CzgResult.success(mkShareBaseService.getShareBase(shopId)); + } /** * 分享 领取触发 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java index 893f85d8d..1984660dd 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/MkShareBase.java @@ -1,5 +1,6 @@ package com.czg.market.entity; +import com.czg.market.dto.ShopCouponDTO; import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Table; @@ -57,6 +58,11 @@ public class MkShareBase implements Serializable { * 分享人奖励的优惠券ID,关联优惠券表 */ private Long sharerCouponId; + /** + * 分享人奖励的优惠券信息 + */ + @Column(ignore = true) + private ShopCouponDTO sharerCoupon; /** * 分享人奖励的优惠券名称 */ diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java index f27b7f769..14877efb1 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java @@ -39,6 +39,7 @@ public class MkShareBaseServiceImpl extends ServiceImpl Date: Wed, 28 Jan 2026 14:40:54 +0800 Subject: [PATCH 09/20] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AB=AF=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=88=86=E4=BA=AB=E7=9A=84=E5=9F=BA=E7=A1=80=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/controller/user/UCarouselController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java index 242f22a54..ccfe5c164 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java @@ -52,7 +52,7 @@ public class UCarouselController { /** * 分享 基础配置 */ - @PostMapping("/share") + @GetMapping("/share") public CzgResult share(@RequestParam Long shopId) { return CzgResult.success(mkShareBaseService.getShareBase(shopId)); } From fc8599d36c2daee817d1ecff8dc9ca30d343a8c9 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 28 Jan 2026 17:07:50 +0800 Subject: [PATCH 10/20] =?UTF-8?q?=E7=A9=BA=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../market/service/impl/MkCarouselServiceImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java index a660ce30d..e00c742d9 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkCarouselServiceImpl.java @@ -36,9 +36,11 @@ public class MkCarouselServiceImpl extends ServiceImpl list = list(queryWrapper); list.forEach(mkCarousel -> { - MiniAppPages miniAppPages = miniAppPageService.getById(mkCarousel.getJumpPageId()); - if (miniAppPages != null) { - mkCarousel.setJumpPagePath(miniAppPages.getPath()); + if (mkCarousel.getJumpPageId() != null) { + MiniAppPages miniAppPages = miniAppPageService.getById(mkCarousel.getJumpPageId()); + if (miniAppPages != null) { + mkCarousel.setJumpPagePath(miniAppPages.getPath()); + } } }); return list; From abcd0fbc7b5224ce3ff93d2061254d17906b65f8 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 28 Jan 2026 17:27:54 +0800 Subject: [PATCH 11/20] =?UTF-8?q?=E4=B8=8D=E7=9F=A5=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/account/service/ShopConfigService.java | 3 +-- .../service/account/service/impl/ShopConfigServiceImpl.java | 3 +-- .../czg/service/account/service/impl/ShopInfoServiceImpl.java | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java index f4f21941c..a7bc942a9 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java @@ -5,7 +5,6 @@ import com.czg.account.entity.ShopInfo; import com.czg.exception.CzgException; import com.mybatisflex.core.service.IService; -import java.io.Serializable; import java.util.List; /** @@ -16,7 +15,7 @@ import java.util.List; */ public interface ShopConfigService extends IService { - ShopInfo getShopInfoAndConfig(Serializable id) throws CzgException; + ShopInfo getShopInfoAndConfig(Long id) throws CzgException; void editStatusByShopIdList(Long mainShopId, Integer isEnable, boolean onyUpValid, String name, String useShopType, List shopIdList); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java index d74b8b2be..e411597cf 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java @@ -14,7 +14,6 @@ import jakarta.annotation.Resource; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.cache.annotation.Cacheable; -import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -37,7 +36,7 @@ public class ShopConfigServiceImpl extends ServiceImpl i @Override public ShopInfo getById(Serializable id) throws CzgException { - return shopConfigService.getShopInfoAndConfig(id); + return shopConfigService.getShopInfoAndConfig((Long) id); } @Override From 2d15315b7901ce48782668d8ef9802a3233126d8 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Thu, 29 Jan 2026 09:42:50 +0800 Subject: [PATCH 12/20] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/ProductController.java | 49 ++--- .../com/czg/product/dto/ProductExportDTO.java | 173 ++++++++++++++++++ .../czg/product/service/ProductService.java | 4 +- .../java/com/czg/excel/ExcelExportUtil.java | 56 ++++++ .../com/czg/excel/LocalTimeConverter.java | 47 +++++ .../service/impl/ProductServiceImpl.java | 58 +++++- 6 files changed, 354 insertions(+), 33 deletions(-) create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/excel/LocalTimeConverter.java diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java index 85bab5667..82ee8aed2 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java @@ -27,6 +27,7 @@ import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -80,6 +81,14 @@ public class ProductController { return CzgResult.success(map); } + /** + * 导出商品 + */ + @GetMapping("export") + public void exportProduct(ProductDTO param, HttpServletResponse response) { + productService.exportProductList(param, response); + } + /** * 商品-列表 */ @@ -91,9 +100,7 @@ public class ProductController { param.setShopId(shopId); List productList = productService.getProductCacheList(param); productService.refreshProductStock(param, productList); - productList.forEach(prod -> { - prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime())); - }); + productList.forEach(prod -> prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime()))); return CzgResult.success(productList); } @@ -124,9 +131,7 @@ public class ProductController { dto.setShopId(shopId); productService.addProduct(dto); asyncProductToShop(dto.getId()); - ThreadUtil.execAsync(() -> { - rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); - }); + ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId))); return CzgResult.success(); } @@ -153,9 +158,7 @@ public class ProductController { dto.setShopId(shopId); productService.updateProduct(dto); asyncProductToShop(dto.getId()); - ThreadUtil.execAsync(() -> { - rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); - }); + ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId))); return CzgResult.success(); } @@ -167,9 +170,7 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(); param.setShopId(shopId); productService.updateProductStock(param); - ThreadUtil.execAsync(() -> { - rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); - }); + ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId))); return CzgResult.success(); } @@ -188,9 +189,7 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(); productService.deleteProduct(shopId, id); asyncProductToShop(id); - ThreadUtil.execAsync(() -> { - rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); - }); + ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId))); return CzgResult.success(); } @@ -205,9 +204,7 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(); param.setShopId(shopId); productService.onOffProduct(param); - ThreadUtil.execAsync(() -> { - rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); - }); + ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId))); return CzgResult.success(); } @@ -222,9 +219,7 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(); param.setShopId(shopId); productService.markProductIsSoldOut(param); - ThreadUtil.execAsync(() -> { - rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); - }); + ThreadUtil.execAsync(() -> rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId))); return CzgResult.success(); } @@ -321,9 +316,7 @@ public class ProductController { if (shopInfo.getMainId() == null || shopId == shopInfo.getMainId()) { throw new CzgException("不存在主子店铺关系,无需同步商品信息"); } - ThreadUtil.execAsync(() -> { - shopSyncService.sync(shopInfo.getMainId(), shopId, shopId); - }); + ThreadUtil.execAsync(() -> shopSyncService.sync(shopInfo.getMainId(), shopId, shopId)); CzgResult ret = CzgResult.success(); ret.setMsg("操作成功,数据正在后台同步中..."); return ret; @@ -331,15 +324,11 @@ public class ProductController { private void asyncProductToShop(Long id) { long shopId = StpKit.USER.getShopId(0L); - ThreadUtil.execAsync(() -> { - shopSyncService.syncProductBySourceShop(shopId, id, shopId); - }); + ThreadUtil.execAsync(() -> shopSyncService.syncProductBySourceShop(shopId, id, shopId)); } private void asyncConsProToShop(Long id) { long shopId = StpKit.USER.getShopId(0L); - ThreadUtil.execAsync(() -> { - shopSyncService.syncConsProBySourceShop(shopId, id, shopId); - }); + ThreadUtil.execAsync(() -> shopSyncService.syncConsProBySourceShop(shopId, id, shopId)); } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java new file mode 100644 index 000000000..94563c686 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java @@ -0,0 +1,173 @@ +package com.czg.product.dto; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +/** + * 商品导出 + * @author yjjie + * @date 2026/1/28 14:30 + */ +@Data +public class ProductExportDTO { + + @Data + public static class ProductSkuExportDTO { + + @ExcelProperty("条形码") + private String barCode; + + @ExcelProperty("原价") + private BigDecimal originPrice; + + @ExcelProperty("成本价") + private BigDecimal costPrice; + + @ExcelProperty("会员价") + private BigDecimal memberPrice; + + @ExcelProperty("售价") + private BigDecimal salePrice; + + @ExcelProperty("起售数量") + private Integer suitNum; + + @ExcelProperty("规格详情") + private String specInfo; + + @ExcelProperty("是否上架") + private Integer isGrounding; + + + @ExcelProperty("规格名称") + private String name; + } + + @Data + public static class ProductGroupExportDTO { + @ExcelProperty("套餐内商品总数") + private Integer count; + + @ExcelProperty("套餐选几") + private Integer number; + + @ExcelProperty("套餐名称") + private String title; + + @ExcelProperty("套餐内商品列表") + private List goods = new ArrayList<>(); + + @Data + public static class FoodExportDTO { + + @ExcelProperty("商品名称") + private String proName; + + @ExcelProperty("规格名称") + private String skuName; + } + } + + @ExcelProperty("商品名称") + private String name; + + @ExcelProperty("商品分类名称") + private String categoryName; + + @ExcelProperty("条码") + private String barCode; + + @ExcelProperty("商品规格名称") + private String specFullName; + + @ExcelProperty("售价") + private BigDecimal price; + @ExcelProperty("会员价") + private BigDecimal memberPrice; + + @ExcelProperty("商品单位名称") + private String unitName; + + /** + * 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券 + */ + @ExcelProperty("商品类型") + private String type; + + /** + * 套餐类型 0 固定套餐 1可选套餐 + */ + @ExcelIgnore + private Integer groupType; + @ExcelProperty("套餐类型") + private String groupTypeRemark; + + /** + * 可用开始时间 + */ + @ExcelProperty("可用开始时间") + private LocalTime startTime; + /** + * 可用结束时间 + */ + @ExcelProperty("可用结束时间") + private LocalTime endTime; + + /** + * 商品级库存数量 + */ + @ExcelProperty("库存数量") + private Integer stockNumber; + + /** + * 是否上架 + */ + @ExcelIgnore + private Integer isSale; + @ExcelProperty("是否上架") + private String isSaleRemark; + + + @ExcelIgnore + private List skuList; + + @ExcelIgnore + private List proGroupVo; + + + public String getType() { + return switch (type) { + case "single" -> "单规格商品"; + case "sku" -> "多规格商品"; + case "package" -> "套餐商品"; + case "weight" -> "称重商品"; + case "coupon" -> "团购券"; + case null, default -> "未知类型"; + }; + } + + public String getGroupTypeRemark() { + if (!"package".equals(type)) { + return ""; + } + return switch (groupType) { + case 0 -> "固定套餐"; + case 1 -> "可选套餐"; + case null, default -> "未知类型"; + }; + } + + public String getIsSaleRemark() { + return switch (isSale) { + case 0 -> "下架"; + case 1 -> "上架"; + case null, default -> "未知状态"; + }; + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java index f24801f20..420b7a7e0 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java @@ -1,13 +1,13 @@ package com.czg.product.service; import com.czg.product.dto.ProductDTO; -import com.czg.product.dto.RelatedProductDTO; import com.czg.product.entity.Product; import com.czg.product.entity.ProductStockFlow; import com.czg.product.param.*; import com.czg.product.vo.ProductStatisticsVo; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; +import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -34,6 +34,8 @@ public interface ProductService extends IService { */ List getProductList(ProductDTO param); + void exportProductList(ProductDTO param, HttpServletResponse response); + /** * 从缓存里面获取商品列表 * diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java index ba1d6d570..b5030ddd4 100644 --- a/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java @@ -3,6 +3,8 @@ package com.czg.excel; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.write.builder.ExcelWriterBuilder; +import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; @@ -244,4 +246,58 @@ public class ExcelExportUtil { } return count; } + + /** + * 带合并单元格的商品导出到Response + * + * @param data 数据列表 + * @param fileName 文件名 + * @param response HttpServletResponse + * @param 数据类型 + */ + public static void exportProductWithMergeToResponse(List data, Class clazz, + String fileName, + HttpServletResponse response, List handlers) { + if (data == null) { + data = Collections.emptyList(); + } + + setResponseHeader(response, fileName, DEFAULT_CONFIG); + + try (OutputStream outputStream = response.getOutputStream()) { + // 创建样式策略 - 设置表头和内容都居中 + WriteCellStyle headStyle = new WriteCellStyle(); + headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + + WriteCellStyle contentStyle = new WriteCellStyle(); + contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + + HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy(headStyle, contentStyle); + + // 创建写入器 - 必须指定clazz + ExcelWriterBuilder builder = EasyExcel.write(outputStream, clazz) + .autoCloseStream(true) + .registerConverter(new LocalTimeConverter()) + .registerWriteHandler(styleStrategy); + + if (handlers != null && !handlers.isEmpty()) { + for (SheetWriteHandler h : handlers) { + builder.registerWriteHandler(h); + } + } + + ExcelWriter excelWriter = builder.build(); + + WriteSheet writeSheet = EasyExcel.writerSheet(DEFAULT_CONFIG.getDefaultSheetName()).build(); + + excelWriter.write(data, writeSheet); + excelWriter.finish(); + + log.info("带合并单元格的商品Excel导出成功,文件名:{},数据量:{}", fileName, data.size()); + } catch (IOException e) { + log.error("带合并单元格的商品Excel导出失败", e); + throw new CzgException("Excel导出失败", e); + } + } + } diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/LocalTimeConverter.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/LocalTimeConverter.java new file mode 100644 index 000000000..3672f9af8 --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/LocalTimeConverter.java @@ -0,0 +1,47 @@ +package com.czg.excel; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * @author yjjie + * @date 2026/1/28 16:16 + */ +public class LocalTimeConverter implements Converter { + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); + + @Override + public Class supportJavaTypeKey() { + return LocalTime.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public LocalTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String stringValue = cellData.getStringValue(); + if (stringValue == null || stringValue.trim().isEmpty()) { + return null; + } + return LocalTime.parse(stringValue, FORMATTER); + } + + @Override + public WriteCellData convertToExcelData(LocalTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + if (value == null) { + return new WriteCellData<>(""); + } + return new WriteCellData<>(value.format(FORMATTER)); + } +} diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java index 3d85750b7..fe58280ae 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java @@ -5,11 +5,14 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONWriter; import com.czg.constant.CacheConstant; import com.czg.constants.SystemConstants; +import com.czg.excel.ExcelExportUtil; import com.czg.exception.CzgException; import com.czg.product.dto.*; import com.czg.product.entity.*; @@ -30,6 +33,7 @@ import com.mybatisflex.core.update.UpdateChain; import com.mybatisflex.spring.service.impl.ServiceImpl; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboService; @@ -65,7 +69,6 @@ public class ProductServiceImpl extends ServiceImpl impl private final ProdSkuMapper prodSkuMapper; private final ProdConsRelationMapper prodConsRelationMapper; private final ConsInfoMapper consInfoMapper; - private final ConsStockFlowMapper consStockFlowMapper; private final ProductStockFlowMapper productStockFlowMapper; private final ProductStockFlowService productStockFlowService; private final ConsStockFlowService consStockFlowService; @@ -175,6 +178,57 @@ public class ProductServiceImpl extends ServiceImpl impl return records; } + @Override + public void exportProductList(ProductDTO param, HttpServletResponse response) { + QueryWrapper queryWrapper = buildFullQueryWrapper(param); + List records = super.listAs(queryWrapper, ProductDTO.class); + buildProductExtInfo(records); + + List handlers = new ArrayList<>(); + + List dataList = new ArrayList<>(); + records.forEach(exportDTO -> { + int first = dataList.size() + 1; + if (exportDTO.getSkuList() != null && !exportDTO.getSkuList().isEmpty()) { + exportDTO.getSkuList().forEach(sku -> { + ProductExportDTO dto = new ProductExportDTO(); + BeanUtil.copyProperties(exportDTO, dto); + dto.setSpecFullName(sku.getSpecInfo()); + dto.setPrice(sku.getSalePrice()); + dto.setMemberPrice(sku.getMemberPrice()); + dto.setIsSale(sku.getIsGrounding()); + dto.setBarCode(sku.getBarCode()); + dataList.add(dto); + }); + + if (exportDTO.getSkuList().size() > 1) { + OnceAbsoluteMergeStrategy name = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 0, 0); + handlers.add(name); + OnceAbsoluteMergeStrategy category = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 1, 1); + handlers.add(category); + OnceAbsoluteMergeStrategy unit = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 6, 6); + handlers.add(unit); + OnceAbsoluteMergeStrategy type = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 7, 7); + handlers.add(type); + OnceAbsoluteMergeStrategy groupType = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 8, 8); + handlers.add(groupType); + OnceAbsoluteMergeStrategy startTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 9, 9); + handlers.add(startTime); + OnceAbsoluteMergeStrategy endTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 10, 10); + handlers.add(endTime); + OnceAbsoluteMergeStrategy stockNumber = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 11, 11); + handlers.add(stockNumber); + OnceAbsoluteMergeStrategy createTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 12, 12); + handlers.add(createTime); + } + } else { + dataList.add(BeanUtil.copyProperties(exportDTO, ProductExportDTO.class)); + } + }); + + ExcelExportUtil.exportProductWithMergeToResponse(dataList, ProductExportDTO.class, "商品列表", response, handlers); + } + @Override public List getProductCacheList(ProductDTO param) { Long shopId = param.getShopId(); @@ -555,7 +609,7 @@ public class ProductServiceImpl extends ServiceImpl impl String type = param.getType(); Long id = param.getId(); Integer isSale = param.getIsSale(); - String sensitiveOperation = ""; + String sensitiveOperation; if (isSale == 1) { sensitiveOperation = "上架"; } else { From d71819bd08a68460ff27a8e5ab6ff7ebebc57f0b Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Thu, 29 Jan 2026 09:46:57 +0800 Subject: [PATCH 13/20] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=BF=9B=E4=BB=B6?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/third/wechat/WechatEntryManager.java | 4 ++-- .../entry/business/sales/WechatEntryStoreInfoReqDto.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 39621969e..d7c70f066 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -313,8 +313,8 @@ public class WechatEntryManager { bizStoreInfo.setBizStoreName(baseInfo.getShortName()); bizStoreInfo.setBizAddressCode(storeInfo.getMercAreaCode()); bizStoreInfo.setBizStoreAddress(storeInfo.getBusinessAddress()); - bizStoreInfo.setStoreEntrancePic(storeInfo.getDoorPic().getWechatId()); - bizStoreInfo.setIndoorPic(storeInfo.getInsidePic().getWechatId()); + bizStoreInfo.setStoreEntrancePic(List.of(storeInfo.getDoorPic().getWechatId())); + bizStoreInfo.setIndoorPic(List.of(storeInfo.getInsidePic().getWechatId())); salesInfo.setBizStoreInfo(bizStoreInfo); WechatEntryMiniProgramReqDto miniProgramInfo = new WechatEntryMiniProgramReqDto(); miniProgramInfo.setMiniProgramAppid("wxd88fffa983758a30"); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java index 298741d7e..ae3b8018b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java @@ -55,8 +55,8 @@ public class WechatEntryStoreInfoReqDto { * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 */ @JSONField(name = "store_entrance_pic") -// private List storeEntrancePic; - private String storeEntrancePic; + private List storeEntrancePic; +// private String storeEntrancePic; /** * 【必填】 @@ -65,8 +65,8 @@ public class WechatEntryStoreInfoReqDto { * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 */ @JSONField(name = "indoor_pic") -// private List indoorPic; - private String indoorPic; + private List indoorPic; +// private String indoorPic; /** * 【选填】 From 2b594193eedcbf69d5a6bfb5a796cbc77f34f84d Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Thu, 29 Jan 2026 10:13:46 +0800 Subject: [PATCH 14/20] =?UTF-8?q?=E5=88=86=E4=BA=AB=E9=A2=86=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/service/market/service/impl/MkShareBaseServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java index 14877efb1..c64f97d82 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java @@ -65,7 +65,7 @@ public class MkShareBaseServiceImpl extends ServiceImpl distributionUserService.bindInviteUser(fromUserId, toUserId, shopId)); } MkShareBase shareBase = getById(shopId); - if (shareBase == null || shareBase.getIsEnabled().equals(1) || StrUtil.isBlank(shareBase.getRewardSharePages())) { + if (shareBase == null || !shareBase.getIsEnabled().equals(1) || StrUtil.isBlank(shareBase.getRewardSharePages())) { return; } if (!shareBase.getRewardSharePages().contains(tagType)) { From 6c41777b7c9e34f91a5b2bef8e0c654c2b33391a Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Thu, 29 Jan 2026 10:26:54 +0800 Subject: [PATCH 15/20] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=89=A7=E8=A1=8C=20?= =?UTF-8?q?=E8=80=97=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/task/EntryManagerTask.java | 2 +- .../order-server/src/main/java/com/czg/task/StatisticTask.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java index 738c6850f..796f86f7f 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java @@ -38,7 +38,7 @@ public class EntryManagerTask { log.info("进件查询,定时任务执行"); long start = System.currentTimeMillis(); entryManager(null); - log.info("进件查询,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis()); + log.info("进件查询,定时任务执行完毕,耗时:{}ms", System.currentTimeMillis() - start); } /** diff --git a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java index 2805973b6..160a6c7db 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java @@ -17,6 +17,7 @@ import java.util.List; /** * 统计任务 + * * @author Administrator */ @Component @@ -43,7 +44,7 @@ public class StatisticTask { // 获取前一天 LocalDate yesterday = LocalDate.now().minusDays(1); baseStatistic(yesterday); - log.info("统计数据,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis()); + log.info("统计数据,定时任务执行完毕,耗时:{}ms", System.currentTimeMillis() - start); } From bac24f9ba15e955f9fcc00def3286095ab4c706a Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Thu, 29 Jan 2026 11:22:28 +0800 Subject: [PATCH 16/20] =?UTF-8?q?=E5=8E=BB=E9=87=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../market/service/impl/MkShareBaseServiceImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java index c64f97d82..6d774d416 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShareBaseServiceImpl.java @@ -82,6 +82,13 @@ public class MkShareBaseServiceImpl extends ServiceImpl Date: Thu, 29 Jan 2026 14:47:09 +0800 Subject: [PATCH 17/20] =?UTF-8?q?=E6=89=AB=E7=A0=81=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/controller/pay/OrderPayController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java b/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java index c05dfc8ef..b63cb7d49 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java @@ -179,6 +179,8 @@ public class OrderPayController { public CzgResult> js2PayOrder(HttpServletRequest request, @RequestBody OrderPayParamDTO payParam) { if ("alipay".equals(payParam.getPayType())) { payParam.setPayType(PayCst.Type.ALIPAY); + } else if ("aliPay".equals(payParam.getPayType())) { + payParam.setPayType(PayCst.Type.ALIPAY); } else if ("wechatPay".equals(payParam.getPayType())) { payParam.setPayType(PayCst.Type.WECHAT); } else { From 73929aaac59443af2e2dd178321ae558914a3364 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 30 Jan 2026 09:49:18 +0800 Subject: [PATCH 18/20] =?UTF-8?q?=E8=BD=AE=E6=92=AD=E5=9B=BE=E5=BC=80?= =?UTF-8?q?=E5=85=B3=20=E8=8E=B7=E5=8F=96=E5=9C=B0=E5=9D=80=20=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/controller/user/UCarouselController.java | 1 + .../main/java/com/czg/controller/pay/OrderPayController.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java index ccfe5c164..97a7adf7a 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/user/UCarouselController.java @@ -35,6 +35,7 @@ public class UCarouselController { @GetMapping("/carousel") public CzgResult> getCarousels(MkCarouselDTO carouselDTO) { carouselDTO.setShopId(StpKit.USER.getShopId()); + carouselDTO.setIsEnabled(1); return CzgResult.success(mkCarouselService.getCarousels(carouselDTO)); } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java b/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java index b63cb7d49..90915c136 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/pay/OrderPayController.java @@ -20,6 +20,7 @@ import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.beans.factory.annotation.Value; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -44,6 +45,8 @@ public class OrderPayController { private OrderInfoService orderInfoService; @DubboReference private SysParamsService paramsService; + @Value("${spring.profiles.active}") + private String env; @PostMapping("/creditPay") @Debounce(value = "#payParam.checkOrderPay.orderId") @@ -154,6 +157,7 @@ public class OrderPayController { AssertUtil.isNull(shopId, "店铺id不能为空"); AssertUtil.isNull(checkOrderPay, "订单信息不能为空"); Map map = new HashMap<>(); + map.put("env", env); map.put("shopId", shopId); map.put("orderId", checkOrderPay.getOrderId()); map.put("payAmount", checkOrderPay.getOrderAmount()); From 496c93167892599e09d115bc08c78b86404c5c55 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 30 Jan 2026 14:13:02 +0800 Subject: [PATCH 19/20] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/product/dto/ProductExportDTO.java | 107 ++--------- .../product/dto/ProductPackageExportDTO.java | 101 ++++++++++ .../java/com/czg/excel/ExcelExportUtil.java | 63 ++++--- .../main/java/com/czg/excel/SheetData.java | 21 +++ .../service/impl/ProductServiceImpl.java | 174 ++++++++++++++---- 5 files changed, 318 insertions(+), 148 deletions(-) create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductPackageExportDTO.java create mode 100644 cash-common/cash-common-tools/src/main/java/com/czg/excel/SheetData.java diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java index 94563c686..a86269586 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductExportDTO.java @@ -2,12 +2,11 @@ package com.czg.product.dto; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; import lombok.Data; import java.math.BigDecimal; import java.time.LocalTime; -import java.util.ArrayList; -import java.util.List; /** * 商品导出 @@ -17,112 +16,61 @@ import java.util.List; @Data public class ProductExportDTO { - @Data - public static class ProductSkuExportDTO { - - @ExcelProperty("条形码") - private String barCode; - - @ExcelProperty("原价") - private BigDecimal originPrice; - - @ExcelProperty("成本价") - private BigDecimal costPrice; - - @ExcelProperty("会员价") - private BigDecimal memberPrice; - - @ExcelProperty("售价") - private BigDecimal salePrice; - - @ExcelProperty("起售数量") - private Integer suitNum; - - @ExcelProperty("规格详情") - private String specInfo; - - @ExcelProperty("是否上架") - private Integer isGrounding; - - - @ExcelProperty("规格名称") - private String name; - } - - @Data - public static class ProductGroupExportDTO { - @ExcelProperty("套餐内商品总数") - private Integer count; - - @ExcelProperty("套餐选几") - private Integer number; - - @ExcelProperty("套餐名称") - private String title; - - @ExcelProperty("套餐内商品列表") - private List goods = new ArrayList<>(); - - @Data - public static class FoodExportDTO { - - @ExcelProperty("商品名称") - private String proName; - - @ExcelProperty("规格名称") - private String skuName; - } - } - @ExcelProperty("商品名称") + @ColumnWidth(20) private String name; - @ExcelProperty("商品分类名称") + @ExcelProperty("商品分类") + @ColumnWidth(15) private String categoryName; @ExcelProperty("条码") + @ColumnWidth(20) private String barCode; - @ExcelProperty("商品规格名称") + @ExcelProperty("商品规格") + @ColumnWidth(20) private String specFullName; @ExcelProperty("售价") + @ColumnWidth(10) private BigDecimal price; @ExcelProperty("会员价") + @ColumnWidth(10) private BigDecimal memberPrice; + @ExcelProperty("成本价") + @ColumnWidth(10) + private BigDecimal costPrice; - @ExcelProperty("商品单位名称") + @ExcelProperty("商品单位") + @ColumnWidth(10) private String unitName; /** * 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券 */ @ExcelProperty("商品类型") + @ColumnWidth(15) private String type; - /** - * 套餐类型 0 固定套餐 1可选套餐 - */ - @ExcelIgnore - private Integer groupType; - @ExcelProperty("套餐类型") - private String groupTypeRemark; - /** * 可用开始时间 */ @ExcelProperty("可用开始时间") + @ColumnWidth(16) private LocalTime startTime; /** * 可用结束时间 */ @ExcelProperty("可用结束时间") + @ColumnWidth(16) private LocalTime endTime; /** * 商品级库存数量 */ @ExcelProperty("库存数量") + @ColumnWidth(10) private Integer stockNumber; /** @@ -131,16 +79,10 @@ public class ProductExportDTO { @ExcelIgnore private Integer isSale; @ExcelProperty("是否上架") + @ColumnWidth(10) private String isSaleRemark; - @ExcelIgnore - private List skuList; - - @ExcelIgnore - private List proGroupVo; - - public String getType() { return switch (type) { case "single" -> "单规格商品"; @@ -152,17 +94,6 @@ public class ProductExportDTO { }; } - public String getGroupTypeRemark() { - if (!"package".equals(type)) { - return ""; - } - return switch (groupType) { - case 0 -> "固定套餐"; - case 1 -> "可选套餐"; - case null, default -> "未知类型"; - }; - } - public String getIsSaleRemark() { return switch (isSale) { case 0 -> "下架"; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductPackageExportDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductPackageExportDTO.java new file mode 100644 index 000000000..9036e6c61 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductPackageExportDTO.java @@ -0,0 +1,101 @@ +package com.czg.product.dto; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +/** + * 套餐商品导出 + * @author yjjie + * @date 2026/1/30 10:26 + */ +@Data +@Accessors(chain = true) +public class ProductPackageExportDTO { + + @ExcelProperty("套餐名称") + @ColumnWidth(20) + private String name; + + @ExcelProperty("套餐分类") + @ColumnWidth(15) + private String categoryName; + + @ExcelProperty("售价") + @ColumnWidth(10) + private BigDecimal price; + @ExcelProperty("会员价") + @ColumnWidth(10) + private BigDecimal memberPrice; + + /** + * 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券 + */ + @ExcelIgnore() + private String type; + + /** + * 套餐类型 0 固定套餐 1可选套餐 + */ + @ExcelIgnore + private Integer groupType; + @ExcelProperty("套餐类型") + @ColumnWidth(15) + private String groupTypeRemark; + + @ExcelProperty("组名称") + @ColumnWidth(15) + private String groupTitleName; + + @ExcelProperty("商品名称") + @ColumnWidth(21) + private String groupProductName; + + @ExcelProperty("商品单位") + @ColumnWidth(10) + private String unitName; + + @ExcelProperty("套餐内选择数量") + @ColumnWidth(10) + private String groupProductNumber; + + /** + * 商品级库存数量 + */ + @ExcelProperty("库存数量") + @ColumnWidth(10) + private Integer stockNumber; + + /** + * 是否上架 + */ + @ExcelIgnore + private Integer isSale; + @ExcelProperty("是否上架") + @ColumnWidth(10) + private String isSaleRemark; + + public String getGroupTypeRemark() { + if (!"package".equals(type)) { + return ""; + } + return switch (groupType) { + case 0 -> "固定套餐"; + case 1 -> "可选套餐"; + case null, default -> "未知类型"; + }; + } + + public String getIsSaleRemark() { + return switch (isSale) { + case 0 -> "下架"; + case 1 -> "上架"; + case null, default -> "未知状态"; + }; + } + +} diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java index b5030ddd4..fffa512d7 100644 --- a/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/ExcelExportUtil.java @@ -1,9 +1,12 @@ package com.czg.excel; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.write.builder.ExcelWriterBuilder; +import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.style.WriteCellStyle; @@ -248,54 +251,66 @@ public class ExcelExportUtil { } /** - * 带合并单元格的商品导出到Response + * 带合并单元格的导出到Response + * 多sheet导出到response * - * @param data 数据列表 + * @param sheetDataList 数据列表 * @param fileName 文件名 * @param response HttpServletResponse - * @param 数据类型 */ - public static void exportProductWithMergeToResponse(List data, Class clazz, - String fileName, - HttpServletResponse response, List handlers) { - if (data == null) { - data = Collections.emptyList(); + public static void exportMultipleSheetsToResponse(List sheetDataList, + String fileName, + HttpServletResponse response) { + if (CollectionUtil.isEmpty(sheetDataList)) { + throw new CzgException("数据列表不能为空"); } setResponseHeader(response, fileName, DEFAULT_CONFIG); try (OutputStream outputStream = response.getOutputStream()) { - // 创建样式策略 - 设置表头和内容都居中 + // 创建样式策略 WriteCellStyle headStyle = new WriteCellStyle(); - headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + headStyle.setHorizontalAlignment(HorizontalAlignment.LEFT); + headStyle.setVerticalAlignment(VerticalAlignment.CENTER); WriteCellStyle contentStyle = new WriteCellStyle(); - contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + contentStyle.setHorizontalAlignment(HorizontalAlignment.LEFT); + contentStyle.setVerticalAlignment(VerticalAlignment.CENTER); HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy(headStyle, contentStyle); - // 创建写入器 - 必须指定clazz - ExcelWriterBuilder builder = EasyExcel.write(outputStream, clazz) + // 创建ExcelWriter + ExcelWriterBuilder builder = EasyExcel.write(outputStream) .autoCloseStream(true) .registerConverter(new LocalTimeConverter()) .registerWriteHandler(styleStrategy); - if (handlers != null && !handlers.isEmpty()) { - for (SheetWriteHandler h : handlers) { - builder.registerWriteHandler(h); - } - } - ExcelWriter excelWriter = builder.build(); - WriteSheet writeSheet = EasyExcel.writerSheet(DEFAULT_CONFIG.getDefaultSheetName()).build(); + // 逐个写入sheet + for (int i = 0; i < sheetDataList.size(); i++) { + SheetData sheetData = sheetDataList.get(i); + String sheetName = StrUtil.isNotBlank(sheetData.getSheetName()) + ? sheetData.getSheetName() + : DEFAULT_CONFIG.getDefaultSheetName() + (i + 1); + + ExcelWriterSheetBuilder sheetBuilder = EasyExcel.writerSheet(sheetName); + + // 注册该sheet的合并处理器 + if (sheetData.getHandlers() != null && !sheetData.getHandlers().isEmpty()) { + for (SheetWriteHandler handler : sheetData.getHandlers()) { + sheetBuilder.registerWriteHandler(handler); + } + } + + WriteSheet writeSheet = sheetBuilder.head(sheetData.getClazz()).build(); + excelWriter.write(sheetData.getData(), writeSheet); + } - excelWriter.write(data, writeSheet); excelWriter.finish(); - - log.info("带合并单元格的商品Excel导出成功,文件名:{},数据量:{}", fileName, data.size()); + log.info("多sheet商品Excel导出成功,文件名:{},共{}个sheet", fileName, sheetDataList.size()); } catch (IOException e) { - log.error("带合并单元格的商品Excel导出失败", e); + log.error("多sheet商品Excel导出失败", e); throw new CzgException("Excel导出失败", e); } } diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/excel/SheetData.java b/cash-common/cash-common-tools/src/main/java/com/czg/excel/SheetData.java new file mode 100644 index 000000000..806bbc7c9 --- /dev/null +++ b/cash-common/cash-common-tools/src/main/java/com/czg/excel/SheetData.java @@ -0,0 +1,21 @@ +package com.czg.excel; + +import com.alibaba.excel.write.handler.SheetWriteHandler; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 多sheet导出数据封装类 + * @author yjjie + * @date 2026/1/30 10:53 + */ +@Data +@Accessors(chain = true) +public class SheetData { + private List data; + private Class clazz; + private String sheetName; + private List handlers; +} diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java index fe58280ae..d80c65797 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductServiceImpl.java @@ -13,12 +13,14 @@ import com.alibaba.fastjson2.JSONWriter; import com.czg.constant.CacheConstant; import com.czg.constants.SystemConstants; import com.czg.excel.ExcelExportUtil; +import com.czg.excel.SheetData; import com.czg.exception.CzgException; import com.czg.product.dto.*; import com.czg.product.entity.*; import com.czg.product.enums.*; import com.czg.product.param.*; import com.czg.product.service.*; +import com.czg.product.vo.ProductGroupVo; import com.czg.product.vo.ProductStatisticsVo; import com.czg.sa.StpKit; import com.czg.service.RedisService; @@ -47,6 +49,7 @@ import java.time.LocalDate; import java.time.LocalTime; import java.time.format.TextStyle; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import static com.czg.constant.CacheConstant.ADMIN_CLIENT_PRODUCT_LIST; @@ -141,6 +144,7 @@ public class ProductServiceImpl extends ServiceImpl impl private void buildProductExtInfo(List records) { records.forEach(record -> { record.setIsSaleTime(calcIsSaleTime(record.getDays(), record.getStartTime(), record.getEndTime())); + record.setProGroupVo(JSONArray.parseArray(record.getGroupSnap().toString(), ProductGroupVo.class)); List skuList = prodSkuMapper.selectListByQueryAs(query().eq(ProdSku::getProductId, record.getId()).eq(ProdSku::getIsDel, SystemConstants.OneZero.ZERO), ProdSkuDTO.class); if (CollUtil.isNotEmpty(skuList)) { Optional lowPriceIsPresent = skuList.stream().map(obj -> NumberUtil.nullToZero(obj.getSalePrice())).min(BigDecimal::compareTo); @@ -180,53 +184,151 @@ public class ProductServiceImpl extends ServiceImpl impl @Override public void exportProductList(ProductDTO param, HttpServletResponse response) { + // 1. 查询并构建完整数据 QueryWrapper queryWrapper = buildFullQueryWrapper(param); List records = super.listAs(queryWrapper, ProductDTO.class); buildProductExtInfo(records); + // 2. 分别处理普通商品和套餐商品 + SheetData normalSheet = buildNormalProductSheet(records); + SheetData packageSheet = buildPackageProductSheet(records); + + // 3. 导出 + List dataList = List.of(normalSheet, packageSheet); + ExcelExportUtil.exportMultipleSheetsToResponse(dataList, "商品列表", response); + } + + // ----------------------------- + // 普通商品处理 + // ----------------------------- + private SheetData buildNormalProductSheet(List records) { List handlers = new ArrayList<>(); - List dataList = new ArrayList<>(); - records.forEach(exportDTO -> { - int first = dataList.size() + 1; - if (exportDTO.getSkuList() != null && !exportDTO.getSkuList().isEmpty()) { - exportDTO.getSkuList().forEach(sku -> { - ProductExportDTO dto = new ProductExportDTO(); - BeanUtil.copyProperties(exportDTO, dto); - dto.setSpecFullName(sku.getSpecInfo()); - dto.setPrice(sku.getSalePrice()); - dto.setMemberPrice(sku.getMemberPrice()); - dto.setIsSale(sku.getIsGrounding()); - dto.setBarCode(sku.getBarCode()); - dataList.add(dto); - }); - if (exportDTO.getSkuList().size() > 1) { - OnceAbsoluteMergeStrategy name = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 0, 0); - handlers.add(name); - OnceAbsoluteMergeStrategy category = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 1, 1); - handlers.add(category); - OnceAbsoluteMergeStrategy unit = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 6, 6); - handlers.add(unit); - OnceAbsoluteMergeStrategy type = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 7, 7); - handlers.add(type); - OnceAbsoluteMergeStrategy groupType = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 8, 8); - handlers.add(groupType); - OnceAbsoluteMergeStrategy startTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 9, 9); - handlers.add(startTime); - OnceAbsoluteMergeStrategy endTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 10, 10); - handlers.add(endTime); - OnceAbsoluteMergeStrategy stockNumber = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 11, 11); - handlers.add(stockNumber); - OnceAbsoluteMergeStrategy createTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 12, 12); - handlers.add(createTime); + for (ProductDTO dto : records) { + if ("package".equals(dto.getType())) continue; // 跳过套餐 + + int firstRow = dataList.size() + 1; + + if (dto.getSkuList() != null && !dto.getSkuList().isEmpty()) { + for (ProdSkuDTO sku : dto.getSkuList()) { + ProductExportDTO exportDto = new ProductExportDTO(); + BeanUtil.copyProperties(dto, exportDto); + exportDto.setSpecFullName(sku.getSpecInfo()); + exportDto.setPrice(sku.getSalePrice()); + exportDto.setMemberPrice(sku.getMemberPrice()); + exportDto.setIsSale(sku.getIsGrounding()); + exportDto.setBarCode(sku.getBarCode()); + exportDto.setCostPrice(sku.getCostPrice()); + dataList.add(exportDto); + } + + int skuCount = dto.getSkuList().size(); + if (skuCount > 1) { + mergeColumns(handlers, firstRow, firstRow + skuCount - 1, + 0, 1, 7, 8, 9, 10, 11); // 多列合并 } } else { - dataList.add(BeanUtil.copyProperties(exportDTO, ProductExportDTO.class)); + dataList.add(BeanUtil.copyProperties(dto, ProductExportDTO.class)); } - }); + } - ExcelExportUtil.exportProductWithMergeToResponse(dataList, ProductExportDTO.class, "商品列表", response, handlers); + return new SheetData() + .setSheetName("普通商品") + .setData(dataList) + .setClazz(ProductExportDTO.class) + .setHandlers(handlers); + } + + // ----------------------------- + // 套餐商品处理 + // ----------------------------- + private SheetData buildPackageProductSheet(List records) { + List handlers = new ArrayList<>(); + List dataList = new ArrayList<>(); + + for (ProductDTO exportDTO : records) { + if (!"package".equals(exportDTO.getType())) continue; + + if (exportDTO.getProGroupVo() == null || exportDTO.getProGroupVo().isEmpty()) { + dataList.add(BeanUtil.copyProperties(exportDTO, ProductPackageExportDTO.class)); + continue; + } + + int sheetFirstRow = dataList.size() + 1; + boolean needOuterMerge = exportDTO.getProGroupVo().size() > 1; + + for (ProductGroupVo proGroupDTO : exportDTO.getProGroupVo()) { + int groupFirstRow = dataList.size() + 1; + List goods = proGroupDTO.getGoods(); + int groupSize = goods.size(); + + // 添加每条商品记录 + for (ProductGroupVo.Food good : goods) { + ProductPackageExportDTO pkgDto = new ProductPackageExportDTO() + .setName(exportDTO.getName()) + .setCategoryName(exportDTO.getCategoryName()) + .setUnitName(exportDTO.getUnitName()) + .setPrice(getMainSkuPrice(exportDTO)) + .setMemberPrice(getMainSkuMemberPrice(exportDTO)) + .setType(exportDTO.getType()) + .setGroupType(exportDTO.getGroupType()) + .setStockNumber(exportDTO.getStockNumber()) + .setIsSale(getMainSkuIsSale(exportDTO)) + .setGroupTitleName(proGroupDTO.getTitle()) + .setGroupProductNumber(Optional.ofNullable(proGroupDTO.getNumber()).map(String::valueOf).orElse("")) + .setGroupProductName(good.getProName() + " " + good.getSkuName()); + dataList.add(pkgDto); + } + + // 组内合并:如果该组有多个商品 + if (groupSize > 1) { + needOuterMerge = true; + mergeColumns(handlers, groupFirstRow, groupFirstRow + groupSize - 1, 5, 8); + } + } + + // 外层合并:整个套餐的信息(名称、分类等) + if (needOuterMerge) { + int lastRow = dataList.size(); + mergeColumns(handlers, sheetFirstRow, lastRow, 0, 1, 2, 3, 4); + } + } + + return new SheetData() + .setSheetName("套餐商品") + .setData(dataList) + .setClazz(ProductPackageExportDTO.class) + .setHandlers(handlers); + } + + // ----------------------------- + // 辅助方法:提取主 SKU 信息(避免重复 getFirst()) + // ----------------------------- + private BigDecimal getMainSkuPrice(ProductDTO dto) { + return dto.getSkuList().isEmpty() ? null : dto.getSkuList().getFirst().getSalePrice(); + } + + private BigDecimal getMainSkuMemberPrice(ProductDTO dto) { + return dto.getSkuList().isEmpty() ? null : dto.getSkuList().getFirst().getMemberPrice(); + } + + private Integer getMainSkuIsSale(ProductDTO dto) { + return dto.getSkuList().isEmpty() ? null : dto.getSkuList().getFirst().getIsSale(); + } + + // ----------------------------- + // 合并工具方法:支持多列合并 + // ----------------------------- + private void mergeColumns(List handlers, int firstRow, int lastRow, int... columns) { + for (int col : columns) { + addMergeHandler(handlers, firstRow, lastRow, col, col); + } + } + + private void addMergeHandler(List handlers, int firstRow, int lastRow, int firstCol, int lastCol) { + OnceAbsoluteMergeStrategy strategy = new OnceAbsoluteMergeStrategy(firstRow, lastRow, firstCol, lastCol); + handlers.add(strategy); } @Override From c974f9e0920fdcbbdeca5a55effe050bc45a3306 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 30 Jan 2026 14:38:31 +0800 Subject: [PATCH 20/20] =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/controller/admin/ProductController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java index 82ee8aed2..2baf25503 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java @@ -72,10 +72,10 @@ public class ProductController { public CzgResult> getProductPage(ProductDTO param) { Page data = productService.getProductPage(param); Map map = JSONObject.parseObject(JSONObject.toJSONString(data), Map.class); - if(data.getRecords() != null){ + if (data.getRecords() != null && !data.getRecords().isEmpty()) { ProductDTO first = data.getRecords().getFirst(); map.put("warnLine", first.getWarnLine()); - }else { + } else { map.put("warnLine", 0); } return CzgResult.success(map);