| | |
| | | package cn.lili.modules.lmk.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.lili.common.exception.ServiceException; |
| | | import cn.lili.common.security.AuthUser; |
| | | import cn.lili.common.security.context.UserContext; |
| | |
| | | import cn.lili.modules.lmk.enums.general.StoreCouponStausEnum; |
| | | import cn.lili.modules.lmk.service.StoreCouponService; |
| | | import cn.lili.modules.lmk.service.StoreCouponSingleService; |
| | | import cn.lili.modules.order.order.entity.dto.CouponExportDetailDTO; |
| | | import cn.lili.modules.order.order.entity.dto.StoreCouponClaimRecordDTO; |
| | | import cn.lili.modules.order.order.entity.enums.ClaimStatusEnum; |
| | | import cn.lili.modules.promotion.entity.dos.MemberCoupon; |
| | | import cn.lili.modules.promotion.entity.dto.search.MemberCouponSearchParams; |
| | | import cn.lili.modules.promotion.entity.vos.MemberCouponVO; |
| | | import cn.lili.modules.promotion.service.MemberCouponService; |
| | | import cn.lili.rocketmq.RocketmqSendCallbackBuilder; |
| | | import com.alibaba.fastjson.JSON; |
| | |
| | | import cn.lili.modules.lmk.domain.form.StoreCouponClaimRecordForm; |
| | | import cn.lili.modules.lmk.domain.vo.StoreCouponClaimRecordVO; |
| | | import cn.lili.modules.lmk.domain.query.StoreCouponClaimRecordQuery; |
| | | import org.apache.poi.ss.usermodel.Cell; |
| | | import org.apache.poi.ss.usermodel.Row; |
| | | import org.apache.poi.ss.usermodel.Sheet; |
| | | import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import org.springframework.transaction.support.TransactionSynchronizationManager; |
| | | import org.springframework.util.Assert; |
| | | |
| | | import javax.servlet.ServletOutputStream; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.net.URLEncoder; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | storeCouponSingle.setClaimStatus(ClaimStatusEnum.CLAIM.name()); |
| | | storeCouponSingle.setClaimUserId(userId); |
| | | storeCouponSingle.setClaimUserName(nickName); |
| | | storeCouponSingleService.updateById(storeCouponSingle); |
| | | //校验是否在单品卷类领取过 |
| | | LambdaQueryWrapper<StoreCoupon> storeCoupQuery = Wrappers.<StoreCoupon>lambdaQuery() |
| | | .eq(StoreCoupon::getId, storeCouponSingle.getStoreCoupRef()).last("FOR UPDATE"); |
| | |
| | | throw new ServiceException("当前店铺优惠卷状态异常"); |
| | | } |
| | | //领取对应的优惠卷写入记录 |
| | | memberCouponService.receiveCoupon(storeCouponSingle.getCouponId(),userId , nickName); |
| | | MemberCoupon memberCoupon = memberCouponService.receiveCoupon(storeCouponSingle.getCouponId(), userId, nickName); |
| | | String memberCouponId = memberCoupon.getId(); |
| | | storeCouponSingle.setMemberCouponId(memberCouponId); |
| | | storeCouponSingleService.updateById(storeCouponSingle); |
| | | StoreCouponClaimRecord storeCouponClaimRecord = getStoreCouponClaimRecord(storeCouponSingle, userId); |
| | | storeCouponClaimRecord.setMemberCouponId(memberCouponId); |
| | | this.save(storeCouponClaimRecord); |
| | | LambdaUpdateWrapper<StoreCoupon> updateStoreCoupon = Wrappers.<StoreCoupon>lambdaUpdate().eq(StoreCoupon::getId, storeCoupon.getId()) |
| | | .set(StoreCoupon::getCouponClaimNum, storeCoupon.getCouponClaimNum() + 1) |
| | |
| | | |
| | | } |
| | | } |
| | | private XSSFWorkbook initCouponExportData(List<StoreCouponClaimRecordVO> list) { |
| | | // 转换VO为DTO(如果DTO与VO字段一致,可直接使用VO简化代码) |
| | | List<StoreCouponClaimRecordDTO> dtos = new ArrayList<>(); |
| | | for (StoreCouponClaimRecordVO vo : list) { |
| | | StoreCouponClaimRecordDTO dto = new StoreCouponClaimRecordDTO(); |
| | | BeanUtil.copyProperties(vo, dto); |
| | | dtos.add(dto); |
| | | } |
| | | System.out.println("-----------------------"); |
| | | System.out.println(dtos); |
| | | XSSFWorkbook workbook = new XSSFWorkbook(); |
| | | Sheet sheet = workbook.createSheet("优惠券领取记录"); |
| | | // 创建表头 |
| | | Row header = sheet.createRow(0); |
| | | String[] headers = { |
| | | "会员名称", "优惠券名称", "发布店铺", "面额/折扣", |
| | | "获取方式", "会员优惠券状态", "优惠券类型", |
| | | "使用起始时间", "截止时间" |
| | | }; |
| | | for (int i = 0; i < headers.length; i++) { |
| | | Cell cell = header.createCell(i); |
| | | cell.setCellValue(headers[i]); |
| | | } |
| | | |
| | | // 填充数据(增加空值处理,避免NPE) |
| | | for (int i = 0; i < dtos.size(); i++) { |
| | | StoreCouponClaimRecordDTO dto = dtos.get(i); |
| | | Row row = sheet.createRow(i + 1); |
| | | |
| | | // 1. 会员名称(可能为null) |
| | | row.createCell(0).setCellValue(Objects.nonNull(dto.getMemberName()) ? dto.getMemberName() : ""); |
| | | |
| | | // 2. 优惠券名称(可能为null) |
| | | row.createCell(1).setCellValue(Objects.nonNull(dto.getCouponName()) ? dto.getCouponName() : ""); |
| | | |
| | | // 3. 发布店铺(处理platform特殊值,默认空字符串) |
| | | String storeName = dto.getStoreName(); |
| | | if ("platform".equals(storeName)) { |
| | | row.createCell(2).setCellValue("平台"); |
| | | } else { |
| | | row.createCell(2).setCellValue(Objects.nonNull(storeName) ? storeName : ""); |
| | | } |
| | | |
| | | // 4. 面额/折扣(优先显示折扣,其次显示面额,避免覆盖) |
| | | Cell amountCell = row.createCell(3); |
| | | if (Objects.nonNull(dto.getDiscount())) { |
| | | amountCell.setCellValue(dto.getDiscount() + "折"); |
| | | } else if (Objects.nonNull(dto.getPrice())) { |
| | | amountCell.setCellValue(dto.getPrice() + "元"); // 统一用"元"更规范 |
| | | } else { |
| | | amountCell.setCellValue(""); // 均为空时显示空 |
| | | } |
| | | |
| | | |
| | | // 4. 获取方式(补充默认未知状态,覆盖所有枚举值) |
| | | String getType = dto.getGetType(); |
| | | String getTypeDesc; |
| | | switch (getType) { |
| | | case "FREE": |
| | | getTypeDesc = "免费获取"; |
| | | break; |
| | | case "ACTIVITY": |
| | | getTypeDesc = "活动获取"; |
| | | break; |
| | | case "INSIDE": // 注意:原代码lime是颜色,实际枚举应为INSIDE |
| | | getTypeDesc = "内购"; |
| | | break; |
| | | default: |
| | | getTypeDesc = "未知"; |
| | | } |
| | | row.createCell(4).setCellValue(getTypeDesc); |
| | | |
| | | // 5. 会员优惠券状态(覆盖所有可能状态) |
| | | String status = dto.getMemberCouponStatus(); |
| | | String statusDesc; |
| | | switch (status) { |
| | | case "NEW": |
| | | statusDesc = "已领取"; |
| | | break; |
| | | case "USED": |
| | | statusDesc = "已使用"; |
| | | break; |
| | | case "EXPIRE": |
| | | statusDesc = "已过期"; |
| | | break; |
| | | case "CLOSED": |
| | | statusDesc = "已作废"; |
| | | break; |
| | | default: |
| | | statusDesc = "未知状态"; |
| | | } |
| | | row.createCell(5).setCellValue(statusDesc); |
| | | |
| | | // 6. 优惠券类型(补充默认处理) |
| | | String couponType = dto.getCouponType(); |
| | | String couponTypeDesc; |
| | | if ("DISCOUNT".equals(couponType)) { |
| | | couponTypeDesc = "打折"; |
| | | } else if ("PRICE".equals(couponType)) { |
| | | couponTypeDesc = "减免现金"; |
| | | } else { |
| | | couponTypeDesc = "未知类型"; |
| | | } |
| | | row.createCell(6).setCellValue(couponTypeDesc); |
| | | |
| | | |
| | | // 10. 使用起始时间(处理null,格式化时间) |
| | | Cell startTimeCell = row.createCell(7); |
| | | if (Objects.nonNull(dto.getStartTime())) { |
| | | startTimeCell.setCellValue(DateUtil.formatDateTime(dto.getStartTime())); |
| | | } else { |
| | | startTimeCell.setCellValue(""); |
| | | } |
| | | |
| | | // 11. 截止时间(同上) |
| | | Cell endTimeCell = row.createCell(8); |
| | | if (Objects.nonNull(dto.getEndTime())) { |
| | | endTimeCell.setCellValue(DateUtil.formatDateTime(dto.getEndTime())); |
| | | } else { |
| | | endTimeCell.setCellValue(""); |
| | | } |
| | | } |
| | | |
| | | return workbook; |
| | | } |
| | | |
| | | @Override |
| | | public void queryExportCoupon(HttpServletResponse response, StoreCouponClaimRecordQuery query) { |
| | | List<StoreCouponClaimRecordVO> exportData = baseMapper.getExportData(query); |
| | | XSSFWorkbook workbook = initCouponExportData(exportData); |
| | | |
| | | try { |
| | | // 设置响应头 |
| | | String fileName = URLEncoder.encode("优惠券领取记录", "UTF-8"); |
| | | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx"); |
| | | |
| | | ServletOutputStream out = response.getOutputStream(); |
| | | workbook.write(out); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | try { |
| | | workbook.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static StoreCouponClaimRecord getStoreCouponClaimRecord(StoreCouponSingle storeCouponSingle, String userId) { |
| | | StoreCouponClaimRecord storeCouponClaimRecord = new StoreCouponClaimRecord(); |