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 1/2] =?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 2/2] =?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); }