From b057df883dc79e7866ee37299286ec0c5dc3f056 Mon Sep 17 00:00:00 2001
From: yanderong <307678080@qq.com>
Date: 星期三, 17 六月 2026 20:20:55 +0800
Subject: [PATCH] feat: 新增出行卡管理相关功能
---
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCardPackage.java | 130 +++++++++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardPackageMapper.java | 15 +
ManagementYKDTravel/guns-admin/src/test/sql/t_travel_card.sql | 28 ++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/travelcard/TravelCardStatusEnum.java | 17 +
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TTravelCardController.java | 132 +++++++++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardPackageService.java | 32 ++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCardPackage.xml | 26 +
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCard.java | 187 +++++++++++++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardServiceImpl.java | 95 ++++++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardMapper.java | 17 +
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardPackageServiceImpl.java | 57 ++++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardService.java | 34 ++
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCard.xml | 13
13 files changed, 783 insertions(+), 0 deletions(-)
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/travelcard/TravelCardStatusEnum.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/travelcard/TravelCardStatusEnum.java
new file mode 100644
index 0000000..53028f6
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/travelcard/TravelCardStatusEnum.java
@@ -0,0 +1,17 @@
+package com.stylefeng.guns.core.common.constant.travelcard;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum TravelCardStatusEnum {
+
+ UN_RECHARGE(1, "未充值"),
+
+ RECHARGED(2, "已充值");
+
+ private final Integer code;
+
+ private final String desc;
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TTravelCardController.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TTravelCardController.java
new file mode 100644
index 0000000..ae83eb6
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TTravelCardController.java
@@ -0,0 +1,132 @@
+package com.stylefeng.guns.modular.system.controller.general;
+
+import com.baomidou.mybatisplus.plugins.Page;
+import com.stylefeng.guns.core.base.controller.BaseController;
+import com.stylefeng.guns.core.common.constant.factory.PageFactory;
+import com.stylefeng.guns.core.util.DateUtil;
+import com.stylefeng.guns.core.util.SinataUtil;
+import com.stylefeng.guns.modular.system.model.*;
+import com.stylefeng.guns.modular.system.service.*;
+import com.stylefeng.guns.modular.system.util.ExcelExportUtil;
+import com.stylefeng.guns.modular.system.util.ResultUtil;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+/**
+ * 出行卡管理控制器
+ *
+ * @author sky
+ * @since 2026-06-17 15:47:58
+ */
+@Slf4j
+@AllArgsConstructor
+@Controller
+@RequestMapping("/travelCard")
+public class TTravelCardController extends BaseController {
+
+ private final String PREFIX = "/system/tTravelCard/";
+
+ private final ITravelCardService travelCardService;
+
+ private final ITravelCardPackageService travelCardPackageService;
+
+ /**
+ * 跳转到用户管理首页
+ */
+ @RequestMapping("")
+ public String index() {
+ return PREFIX + "tTravelCard.html";
+ }
+
+ /**
+ * 跳转到添加页面
+ */
+ @RequestMapping("/tTravelCardAdd")
+ public String showAddCarInsurance(){
+ return PREFIX + "tTravelCardAdd.html";
+ }
+
+
+ /**
+ * 获取出行卡包,管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String name) {
+ Page<Map<String, Object>> page = new PageFactory<Map<String, Object>>().defaultPage();
+ page.setRecords(travelCardPackageService.getTravelCardPackageList(page, name));
+ return super.packForBT(page);
+ }
+
+ /**
+ * 添加出行卡包
+ */
+ @ResponseBody
+ @RequestMapping(value = "/saveTravelCard", method = RequestMethod.POST)
+ public ResultUtil<Integer> saveTravelCard(TravelCardPackage travelCardPackage){
+ Integer id = travelCardPackageService.saveTravelCard(travelCardPackage);
+ return ResultUtil.success(id);
+ }
+
+ /**
+ * 导出出行卡信息
+ */
+ @RequestMapping(value = "/outTravelCard")
+ public void outTravelCard(HttpServletRequest request, HttpServletResponse response, Integer packageId) {
+ List<Map<String, Object>> listMap = travelCardService.getTravelCardByPackageId(packageId);
+
+ // 表格数据【封装】
+ List<List<String>> dataList = new ArrayList<>();
+
+ //第一行显示【封装】
+ List<String> twoList = new ArrayList<String>();
+ twoList.add("总计:");
+ twoList.add(listMap.size() +"条");
+ dataList.add(twoList);
+
+ // 列【封装】
+ List<String> shellList = new ArrayList<String>();
+ shellList.add("卡号");
+ shellList.add("卡密码");
+ shellList.add("卡金额");
+ dataList.add(shellList);
+
+ for (Map<String,Object> object : listMap){
+ // 详细数据列【封装】
+ shellList = new ArrayList<String>();
+
+ if(SinataUtil.isNotEmpty(object.get("cardNo"))){
+ shellList.add(object.get("cardNo").toString());
+ }else{
+ shellList.add("-");
+ }
+ if(SinataUtil.isNotEmpty(object.get("cardPassword"))){
+ shellList.add(object.get("cardPassword").toString());
+ }else{
+ shellList.add("-");
+ }
+ if(SinataUtil.isNotEmpty(object.get("amount"))){
+ shellList.add(object.get("amount").toString());
+ }else{
+ shellList.add("-");
+ }
+ dataList.add(shellList);
+ }
+ try {
+ // 调用工具类进行导出
+ ExcelExportUtil.easySheet("出行卡信息导出记录"+DateUtil.formatDate(new Date(), "YYYYMMddHHmmss"), "=出行卡信息导出记录", dataList,request, response);
+ } catch (Exception e) {
+ log.error("出行卡导出异常:", e);
+ }
+ }
+
+
+
+
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardMapper.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardMapper.java
new file mode 100644
index 0000000..1dd72e8
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardMapper.java
@@ -0,0 +1,17 @@
+package com.stylefeng.guns.modular.system.dao;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.stylefeng.guns.modular.system.model.TravelCard;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+
+public interface TravelCardMapper extends BaseMapper<TravelCard> {
+
+ String getMaxCardNo();
+
+ List<Map<String, Object>> getTravelCardByPackageId(@Param("packageId") Integer packageId);
+
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardPackageMapper.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardPackageMapper.java
new file mode 100644
index 0000000..c5259cf
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/TravelCardPackageMapper.java
@@ -0,0 +1,15 @@
+package com.stylefeng.guns.modular.system.dao;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.baomidou.mybatisplus.plugins.Page;
+import com.stylefeng.guns.modular.system.model.TravelCardPackage;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+
+public interface TravelCardPackageMapper extends BaseMapper<TravelCardPackage> {
+
+ List<Map<String, Object>> getTravelCardPackageList(@Param("page") Page<Map<String, Object>> page, @Param("name") String name);
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCard.xml b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCard.xml
new file mode 100644
index 0000000..a6ce3ac
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCard.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.stylefeng.guns.modular.system.dao.TravelCardMapper">
+
+ <select id="getMaxCardNo" resultType="java.lang.String">
+ select max(cardNo) from t_travel_card
+ </select>
+
+ <select id="getTravelCardByPackageId" resultType="java.util.Map">
+ select * from t_travel_card c where c.packageId = #{packageId}
+ </select>
+
+</mapper>
\ No newline at end of file
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCardPackage.xml b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCardPackage.xml
new file mode 100644
index 0000000..7fb531b
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TravelCardPackage.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.stylefeng.guns.modular.system.dao.TravelCardPackageMapper">
+
+ <!-- 通用查询映射结果 -->
+ <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.TravelCardPackage">
+ <id column="id" property="id" />
+ <result column="name" property="name" />
+ <result column="amount" property="amount" />
+ <result column="total" property="total" />
+ <result column="operator" property="operator" />
+ <result column="insertTime" property="insertTime" />
+ <result column="updateTime" property="updateTime" />
+ </resultMap>
+
+ <select id="getTravelCardPackageList" resultType="java.util.Map" parameterType="com.baomidou.mybatisplus.plugins.Page">
+ SELECT * FROM t_travel_card_package as c
+ <where>
+ <if test="name != null and name != ''">
+ and c.name = #{name}
+ </if>
+ </where>
+ order by c.id desc
+ </select>
+
+</mapper>
\ No newline at end of file
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCard.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCard.java
new file mode 100644
index 0000000..1e9a2b6
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCard.java
@@ -0,0 +1,187 @@
+package com.stylefeng.guns.modular.system.model;
+
+import com.baomidou.mybatisplus.activerecord.Model;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.enums.IdType;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 出行卡包
+ * </p>
+ */
+@TableName("t_travel_card")
+public class TravelCard extends Model<TravelCard> {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键id
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * 卡包ID
+ */
+ private Integer packageId;
+
+ /**
+ * 卡号
+ */
+ private String cardNo;
+
+ /**
+ * 卡密码
+ */
+ private String cardPassword;
+
+ /**
+ * 卡金额
+ */
+ private BigDecimal amount;
+
+ /**
+ * 状态:1未充值,2已充值
+ */
+ private Integer status;
+
+ /**
+ * 充值用户ID
+ */
+ private Integer rechargeUserId;
+
+ /**
+ * 充值用户手机号
+ */
+ private String rechargeUserPhone;
+
+ /**
+ * 充值金额
+ */
+ private BigDecimal rechargeAmount;
+
+ /**
+ * 充值时间
+ */
+ private Date rechargeTime;
+
+ /**
+ * 创建时间
+ */
+ private Date insertTime;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getPackageId() {
+ return packageId;
+ }
+
+ public void setPackageId(Integer packageId) {
+ this.packageId = packageId;
+ }
+
+ public String getCardNo() {
+ return cardNo;
+ }
+
+ public void setCardNo(String cardNo) {
+ this.cardNo = cardNo;
+ }
+
+ public String getCardPassword() {
+ return cardPassword;
+ }
+
+ public void setCardPassword(String cardPassword) {
+ this.cardPassword = cardPassword;
+ }
+
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ public void setAmount(BigDecimal amount) {
+ this.amount = amount;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public Integer getRechargeUserId() {
+ return rechargeUserId;
+ }
+
+ public void setRechargeUserId(Integer rechargeUserId) {
+ this.rechargeUserId = rechargeUserId;
+ }
+
+ public String getRechargeUserPhone() {
+ return rechargeUserPhone;
+ }
+
+ public void setRechargeUserPhone(String rechargeUserPhone) {
+ this.rechargeUserPhone = rechargeUserPhone;
+ }
+
+ public BigDecimal getRechargeAmount() {
+ return rechargeAmount;
+ }
+
+ public void setRechargeAmount(BigDecimal rechargeAmount) {
+ this.rechargeAmount = rechargeAmount;
+ }
+
+ public Date getRechargeTime() {
+ return rechargeTime;
+ }
+
+ public void setRechargeTime(Date rechargeTime) {
+ this.rechargeTime = rechargeTime;
+ }
+
+ public Date getInsertTime() {
+ return insertTime;
+ }
+
+ public void setInsertTime(Date insertTime) {
+ this.insertTime = insertTime;
+ }
+
+ @Override
+ protected Serializable pkVal() {
+ return this.id;
+ }
+
+ @Override
+ public String toString() {
+ return "TravelCard{" +
+ "id=" + id +
+ ", packageId=" + packageId +
+ ", cardNo='" + cardNo + '\'' +
+ ", cardPassword='" + cardPassword + '\'' +
+ ", amount=" + amount +
+ ", status=" + status +
+ ", rechargeUserId=" + rechargeUserId +
+ ", rechargeUserPhone='" + rechargeUserPhone + '\'' +
+ ", rechargeAmount=" + rechargeAmount +
+ ", rechargeTime=" + rechargeTime +
+ ", insertTime=" + insertTime +
+ '}';
+ }
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCardPackage.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCardPackage.java
new file mode 100644
index 0000000..6a1591c
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TravelCardPackage.java
@@ -0,0 +1,130 @@
+package com.stylefeng.guns.modular.system.model;
+
+import com.baomidou.mybatisplus.activerecord.Model;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.enums.IdType;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 出行卡包
+ * </p>
+ */
+@TableName("t_travel_card_package")
+public class TravelCardPackage extends Model<TravelCardPackage> {
+
+ private static final long serialVersionUID = 1L;
+ /**
+ * 主键id
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * 卡包名称
+ */
+ private String name;
+
+ /**
+ * 金额
+ */
+ private BigDecimal amount;
+
+ /**
+ * 数量
+ */
+ private Integer total;
+
+ /**
+ * 操作人
+ */
+ private Integer operator;
+
+ /**
+ * 创建时间
+ */
+ private Date insertTime;
+
+ /**
+ * 更新时间
+ */
+ private Date updateTime;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ public void setAmount(BigDecimal amount) {
+ this.amount = amount;
+ }
+
+ public Integer getTotal() {
+ return total;
+ }
+
+ public void setTotal(Integer total) {
+ this.total = total;
+ }
+
+ public Integer getOperator() {
+ return operator;
+ }
+
+ public void setOperator(Integer operator) {
+ this.operator = operator;
+ }
+
+ public Date getInsertTime() {
+ return insertTime;
+ }
+
+ public void setInsertTime(Date insertTime) {
+ this.insertTime = insertTime;
+ }
+
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ @Override
+ protected Serializable pkVal() {
+ return this.id;
+ }
+
+ @Override
+ public String toString() {
+ return "TravelCardPackage{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ ", amount=" + amount +
+ ", total=" + total +
+ ", operator=" + operator +
+ ", insertTime=" + insertTime +
+ ", updateTime=" + updateTime +
+ '}';
+ }
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardPackageService.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardPackageService.java
new file mode 100644
index 0000000..a77ce9a
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardPackageService.java
@@ -0,0 +1,32 @@
+package com.stylefeng.guns.modular.system.service;
+
+import com.baomidou.mybatisplus.plugins.Page;
+import com.baomidou.mybatisplus.service.IService;
+import com.stylefeng.guns.modular.system.model.TravelCardPackage;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 出行卡包服务
+ * </p>
+ */
+public interface ITravelCardPackageService extends IService<TravelCardPackage> {
+
+
+ /**
+ * 获取出行卡包列表
+ * @param page 分页
+ * @param name 卡包名称
+ * @return 列表数据
+ */
+ List<Map<String, Object>> getTravelCardPackageList(Page<Map<String, Object>> page, String name);
+
+ /**
+ * 保存出行卡包
+ *
+ * @param travelCardPackage 卡包信息
+ */
+ Integer saveTravelCard(TravelCardPackage travelCardPackage);
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardService.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardService.java
new file mode 100644
index 0000000..707020c
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ITravelCardService.java
@@ -0,0 +1,34 @@
+package com.stylefeng.guns.modular.system.service;
+
+import com.baomidou.mybatisplus.service.IService;
+import com.stylefeng.guns.modular.system.model.TravelCard;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 出行卡服务
+ * </p>
+ */
+public interface ITravelCardService extends IService<TravelCard> {
+
+
+ /**
+ * 生成出行卡
+ *
+ * @param packageId 卡包ID
+ * @param amount 卡金额
+ * @param total 卡数量
+ */
+ boolean generateTravelCard(Integer packageId, BigDecimal amount, Integer total);
+
+ /**
+ * 根据卡包查询出行卡
+ *
+ * @param packageId 卡包ID
+ * @return 出行卡列表
+ */
+ List<Map<String, Object>> getTravelCardByPackageId(Integer packageId);
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardPackageServiceImpl.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardPackageServiceImpl.java
new file mode 100644
index 0000000..f514eb4
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardPackageServiceImpl.java
@@ -0,0 +1,57 @@
+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.modular.system.dao.TravelCardPackageMapper;
+import com.stylefeng.guns.modular.system.model.TravelCardPackage;
+import com.stylefeng.guns.modular.system.service.ITravelCardPackageService;
+import com.stylefeng.guns.modular.system.service.ITravelCardService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * <p>
+ * 出行卡包,服务实现类
+ * </p>
+ * @author Lux
+ * @version 1.0.0
+ * @since 2026/6/17 18:21
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class TravelCardPackageServiceImpl extends ServiceImpl<TravelCardPackageMapper, TravelCardPackage> implements ITravelCardPackageService {
+
+ private final ITravelCardService travelCardService;
+
+ /**
+ * 获取出行卡包列表
+ * @param page 分页
+ * @param name 卡包名称
+ * @return 列表数据
+ */
+ public List<Map<String, Object>> getTravelCardPackageList(Page<Map<String, Object>> page, String name) {
+ return this.baseMapper.getTravelCardPackageList(page, name);
+ }
+
+ /**
+ * 保存出行卡包
+ *
+ * @param travelCardPackage 卡包信息
+ */
+ @Transactional
+ public Integer saveTravelCard(TravelCardPackage travelCardPackage) {
+ Optional.ofNullable(travelCardPackage).orElseThrow(() -> new RuntimeException("保存出行卡包数据不能为空!"));
+ this.baseMapper.insert(travelCardPackage);
+ // 生成出行卡
+ boolean flag = travelCardService.generateTravelCard(travelCardPackage.getId(), travelCardPackage.getAmount(), travelCardPackage.getTotal());
+ log.info("出行卡包保存,生成出行卡结果:{}", flag);
+ return travelCardPackage.getId();
+ }
+}
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardServiceImpl.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardServiceImpl.java
new file mode 100644
index 0000000..6741a7f
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/TravelCardServiceImpl.java
@@ -0,0 +1,95 @@
+package com.stylefeng.guns.modular.system.service.impl;
+
+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.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+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 卡数量
+ */
+ 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);
+ }
+ 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);
+ }
+}
diff --git a/ManagementYKDTravel/guns-admin/src/test/sql/t_travel_card.sql b/ManagementYKDTravel/guns-admin/src/test/sql/t_travel_card.sql
new file mode 100644
index 0000000..51b3aa1
--- /dev/null
+++ b/ManagementYKDTravel/guns-admin/src/test/sql/t_travel_card.sql
@@ -0,0 +1,28 @@
+
+CREATE TABLE IF NOT EXISTS `t_travel_card_package` (
+ `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `name` varchar(255) NULL COMMENT '卡包名称',
+ `amount` decimal(10,2) NULL COMMENT '金额',
+ `total` int NULL COMMENT '数量',
+ `operator` int NULL COMMENT '操作人',
+ `insertTime` datetime DEFAULT NULL COMMENT '创建时间',
+ `updateTime` datetime DEFAULT NULL COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出行卡包';
+
+
+CREATE TABLE IF NOT EXISTS `t_travel_card` (
+ `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `packageId` int NULL COMMENT '卡包ID',
+ `cardNo` varchar(50) NULL COMMENT '卡号',
+ `cardPassword` varchar(50) NULL COMMENT '卡密码',
+ `amount` decimal(10,2) NULL COMMENT '卡金额',
+ `status` int NULL COMMENT '状态:1未充值,2已充值',
+ `rechargeUserId` int NULL COMMENT '充值用户ID',
+ `rechargeUserPhone` varchar(50) NULL COMMENT '充值用户手机号',
+ `rechargeAmount` decimal(10,2) NULL COMMENT '充值金额',
+ `rechargeTime` datetime DEFAULT NULL COMMENT '充值时间',
+ `insertTime` datetime DEFAULT NULL COMMENT '创建时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_card_no` (`cardNo`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出行卡';
\ No newline at end of file
--
Gitblit v1.7.1