yanderong
2026-06-18 f31587540395b202e27d815bcea78c7780452183
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.stylefeng.guns.modular.system.service.impl;
 
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.common.constant.travelcard.TravelCardStatusEnum;
import com.stylefeng.guns.modular.system.dao.TravelCardMapper;
import com.stylefeng.guns.modular.system.model.TravelCard;
import com.stylefeng.guns.modular.system.service.ITravelCardService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.*;
 
/**
 * <p>
 *    出行卡,服务实现类
 * </p>
 * @author Lux
 * @version 1.0.0
 * @since 2026/6/17 18:21
 */
@Slf4j
@Service
@AllArgsConstructor
public class TravelCardServiceImpl extends ServiceImpl<TravelCardMapper, TravelCard> implements ITravelCardService {
 
    private static final char[] PASSWORD_CHARS = {'A','B','C','D','E','F','G','H', 'J','K','M','N','P','Q','R','S', 'T','U','V','W','X','Y','Z'};
    private static final SecureRandom RANDOM = new SecureRandom();
 
    /**
     * 生成出行卡
     *
     * @param packageId 卡包ID
     * @param amount 卡金额
     * @param total 卡数量
     */
    @Transactional
    public boolean generateTravelCard(Integer packageId, BigDecimal amount, Integer total) {
        if(Objects.isNull(packageId)) {
            log.error("生成出行卡-卡包ID为空,则不执行生成逻辑!");
            return false;
        }
        if(Objects.isNull(total) || Objects.isNull(amount)) {
            log.error("生成出行卡-金额或数量为空,则不执行生成逻辑!");
            return false;
        }
        // 1、查询当前最大卡号
        String maxCardNo = this.baseMapper.getMaxCardNo();
        int startNo;
        // 第一批卡从011001开始
        if (StringUtils.isBlank(maxCardNo)) {
            startNo = 11001;
        } else {
            startNo = Integer.parseInt(maxCardNo) + 1;
        }
        // 2、生成卡信息
        List<TravelCard> dataList = new ArrayList<>(total);
        Date now = new Date();
        for (int i = 0; i < total; i++) {
            TravelCard card = new TravelCard();
            card.setPackageId(packageId);
            String cardNo = String.format("%06d", startNo + i);
            card.setCardNo(cardNo);    // 卡号
            card.setCardPassword(generatePassword());  // 密码
            card.setAmount(amount); // 金额
            card.setStatus(TravelCardStatusEnum.UN_RECHARGE.getCode());   // 未充值
            card.setInsertTime(now);
            dataList.add(card);
        }
        if(CollectionUtils.isNotEmpty(dataList)) {
            insertBatch(dataList);
        }
        return true;
    }
 
    /**
     * 生成6位密码
     */
    private String generatePassword() {
        StringBuilder sb = new StringBuilder(6);
        for (int i = 0; i < 6; i++) {
            sb.append(PASSWORD_CHARS[RANDOM.nextInt(PASSWORD_CHARS.length)]);
        }
        return sb.toString();
    }
 
    /**
     * 根据卡包查询出行卡
     *
     * @param packageId 卡包ID
     * @return 出行卡列表
     */
    public List<Map<String, Object>> getTravelCardByPackageId(Integer packageId) {
        return this.baseMapper.getTravelCardByPackageId(packageId);
    }
 
    /**
     * 出行卡列表
     *
     * @param page 分页
     * @param packageId 包id
     * @param cardNo 卡号
     * @param rechargeUserPhone 充值用户手机
     * @param status 状态
     * @return 列表数据
     */
    public List<Map<String, Object>> getTravelCardList(Page<Map<String, Object>> page, Integer packageId, String cardNo, String rechargeUserPhone, Integer status) {
 
        return this.baseMapper.getTravelCardList(page, packageId, cardNo, rechargeUserPhone, status);
    }
 
    /**
     * 查询已充值数量
     *
     * @param packageId 包ID
     * @return 充值数量
     */
    public Integer rechargeCount(Integer packageId) {
        return this.baseMapper.rechargeCount(packageId, TravelCardStatusEnum.RECHARGED.getCode());
    }
 
    /**
     * 查询卡包下所有出行卡数量
     *
     * @param packageId 包ID
     * @return 出行卡数量
     */
    public Integer countByPackageId(Integer packageId) {
        return this.baseMapper.rechargeCount(packageId, null);
    }
 
}