package com.tcm.training.admin.member.service;
|
|
import cn.idev.excel.FastExcel;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.tcm.training.admin.common.DateTimes;
|
import com.tcm.training.admin.common.PageResponse;
|
import com.tcm.training.admin.common.PhoneMasker;
|
import com.tcm.training.admin.member.entity.MemberPurchaseOrder;
|
import com.tcm.training.admin.member.excel.MemberPurchaseOrderExcelRow;
|
import com.tcm.training.admin.member.mapper.MemberPurchaseOrderMapper;
|
import com.tcm.training.admin.member.row.MemberPurchaseOrderRow;
|
import com.tcm.training.admin.member.vo.MemberPurchaseOrderListItemVO;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
import java.math.BigDecimal;
|
import java.net.URLEncoder;
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
@Service
|
public class MemberPurchaseOrderAppService {
|
|
private static final String STATUS_WAITING_PAYMENT = "WAITING_PAYMENT";
|
private static final String STATUS_PAID = "PAID";
|
private static final String STATUS_REFUNDED = "REFUNDED";
|
private static final String STATUS_CANCELLED = "CANCELLED";
|
|
private static final String MEMBER_TYPE_MONTH_CARD = "MONTH_CARD";
|
private static final String MEMBER_TYPE_QUARTER_CARD = "QUARTER_CARD";
|
private static final String PAYMENT_METHOD_WECHAT = "WECHAT";
|
private static final String PAYMENT_METHOD_ALIPAY = "ALIPAY";
|
|
private final MemberPurchaseOrderMapper memberPurchaseOrderMapper;
|
|
public MemberPurchaseOrderAppService(MemberPurchaseOrderMapper memberPurchaseOrderMapper) {
|
this.memberPurchaseOrderMapper = memberPurchaseOrderMapper;
|
}
|
|
public PageResponse<MemberPurchaseOrderListItemVO> page(int page,
|
int pageSize,
|
String orderNo,
|
String userPhone,
|
String memberType,
|
String paymentMethod,
|
String status,
|
LocalDateTime createdFrom,
|
LocalDateTime createdTo) {
|
IPage<MemberPurchaseOrderRow> result = memberPurchaseOrderMapper.selectOrderPage(
|
new Page<MemberPurchaseOrderRow>(page, pageSize),
|
trimToNull(orderNo),
|
trimToNull(userPhone),
|
trimToNull(memberType),
|
trimToNull(paymentMethod),
|
normalizeStatus(status),
|
createdFrom,
|
createdTo
|
);
|
return PageResponse.of(toList(result.getRecords()), result.getTotal(), result.getCurrent(), result.getSize());
|
}
|
|
public void export(String orderNo,
|
String userPhone,
|
String memberType,
|
String paymentMethod,
|
String status,
|
LocalDateTime createdFrom,
|
LocalDateTime createdTo,
|
HttpServletResponse response) throws IOException {
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
response.setCharacterEncoding("utf-8");
|
String filename = URLEncoder.encode("会员购买订单", "UTF-8").replace("+", "%20");
|
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + filename + ".xlsx");
|
|
List<MemberPurchaseOrderRow> rows = memberPurchaseOrderMapper.selectOrderList(
|
trimToNull(orderNo),
|
trimToNull(userPhone),
|
trimToNull(memberType),
|
trimToNull(paymentMethod),
|
normalizeStatus(status),
|
createdFrom,
|
createdTo
|
);
|
List<MemberPurchaseOrderExcelRow> exports = new ArrayList<MemberPurchaseOrderExcelRow>();
|
for (MemberPurchaseOrderRow row : rows) {
|
MemberPurchaseOrderExcelRow export = new MemberPurchaseOrderExcelRow();
|
export.setOrderNo(row.getOrderNo());
|
export.setUserNickname(defaultText(row.getUserNickname()));
|
export.setUserPhone(PhoneMasker.mask(row.getUserPhone()));
|
export.setMemberType(memberTypeText(row.getMemberType()));
|
export.setMemberDaysText(memberDaysText(row.getMemberDays()));
|
export.setOrderAmount(row.getOrderAmount());
|
export.setPaymentMethod(paymentMethodText(row.getPaymentMethod()));
|
export.setStatus(statusText(row.getStatus()));
|
export.setRefundAmount(resolveRefundAmount(row.getStatus(), row.getOrderAmount(), row.getRefundAmount()));
|
export.setRefundRemark(defaultText(row.getRefundRemark()));
|
export.setCreatedAt(DateTimes.format(row.getCreatedAt()));
|
exports.add(export);
|
}
|
FastExcel.write(response.getOutputStream(), MemberPurchaseOrderExcelRow.class)
|
.sheet("会员购买订单")
|
.doWrite(exports);
|
}
|
|
public void refund(Long id) {
|
MemberPurchaseOrder order = requireOrder(id);
|
if (!STATUS_PAID.equals(order.getStatus())) {
|
throw new IllegalArgumentException("仅已支付订单允许退款");
|
}
|
// TODO: 支付方案确认后,在这里接入真实退款流程并在退款成功后更新订单状态与退款时间。
|
throw new IllegalArgumentException("退款功能待支付方案确认后接入");
|
}
|
|
@Transactional
|
public void delete(Long id) {
|
MemberPurchaseOrder order = requireOrder(id);
|
if (!STATUS_REFUNDED.equals(order.getStatus())) {
|
throw new IllegalArgumentException("仅已退款订单允许删除");
|
}
|
memberPurchaseOrderMapper.deleteById(id);
|
}
|
|
private MemberPurchaseOrder requireOrder(Long id) {
|
MemberPurchaseOrder order = memberPurchaseOrderMapper.selectOne(new LambdaQueryWrapper<MemberPurchaseOrder>()
|
.eq(MemberPurchaseOrder::getId, id)
|
.eq(MemberPurchaseOrder::getDeleted, 0)
|
.last("limit 1"));
|
if (order == null) {
|
throw new IllegalArgumentException("会员购买订单不存在");
|
}
|
return order;
|
}
|
|
private List<MemberPurchaseOrderListItemVO> toList(List<MemberPurchaseOrderRow> rows) {
|
List<MemberPurchaseOrderListItemVO> list = new ArrayList<MemberPurchaseOrderListItemVO>();
|
for (MemberPurchaseOrderRow row : rows) {
|
MemberPurchaseOrderListItemVO item = new MemberPurchaseOrderListItemVO();
|
item.setId(row.getId());
|
item.setOrderNo(row.getOrderNo());
|
item.setUserNickname(row.getUserNickname());
|
item.setUserPhone(PhoneMasker.mask(row.getUserPhone()));
|
item.setMemberType(row.getMemberType());
|
item.setMemberDays(row.getMemberDays());
|
item.setOrderAmount(row.getOrderAmount());
|
item.setPaymentMethod(row.getPaymentMethod());
|
item.setRefundAmount(resolveRefundAmount(row.getStatus(), row.getOrderAmount(), row.getRefundAmount()));
|
item.setRefundRemark(row.getRefundRemark());
|
item.setStatus(row.getStatus());
|
item.setPaidAt(row.getPaidAt());
|
item.setRefundedAt(row.getRefundedAt());
|
item.setCreatedAt(row.getCreatedAt());
|
list.add(item);
|
}
|
return list;
|
}
|
|
private BigDecimal resolveRefundAmount(String status, BigDecimal orderAmount, BigDecimal refundAmount) {
|
if (!STATUS_REFUNDED.equals(status)) {
|
return null;
|
}
|
return refundAmount == null ? orderAmount : refundAmount;
|
}
|
|
private String normalizeStatus(String status) {
|
String normalized = trimToNull(status);
|
if (normalized == null) {
|
return null;
|
}
|
if (STATUS_PAID.equals(normalized) || STATUS_REFUNDED.equals(normalized)) {
|
return normalized;
|
}
|
return null;
|
}
|
|
private String trimToNull(String value) {
|
if (value == null) {
|
return null;
|
}
|
String trimmed = value.trim();
|
return trimmed.isEmpty() ? null : trimmed;
|
}
|
|
private String defaultText(String value) {
|
return value == null || value.trim().isEmpty() ? "-" : value.trim();
|
}
|
|
private String memberDaysText(Integer memberDays) {
|
return memberDays == null ? "-" : memberDays + "天";
|
}
|
|
private String memberTypeText(String memberType) {
|
if (MEMBER_TYPE_MONTH_CARD.equals(memberType)) {
|
return "月卡";
|
}
|
if (MEMBER_TYPE_QUARTER_CARD.equals(memberType)) {
|
return "季卡";
|
}
|
return "-";
|
}
|
|
private String paymentMethodText(String paymentMethod) {
|
if (PAYMENT_METHOD_WECHAT.equals(paymentMethod)) {
|
return "微信支付";
|
}
|
if (PAYMENT_METHOD_ALIPAY.equals(paymentMethod)) {
|
return "支付宝支付";
|
}
|
return "-";
|
}
|
|
private String statusText(String status) {
|
if (STATUS_WAITING_PAYMENT.equals(status)) {
|
return "待支付";
|
}
|
if (STATUS_PAID.equals(status)) {
|
return "已支付";
|
}
|
if (STATUS_REFUNDED.equals(status)) {
|
return "已退款";
|
}
|
if (STATUS_CANCELLED.equals(status)) {
|
return "已取消";
|
}
|
return "-";
|
}
|
}
|