Parcourir la source

feat: 用户充值模板

xdd il y a 3 semaines
Parent
commit
32fe27aac3

+ 4 - 7
fs-service/src/main/java/com/fs/his/domain/FsUser.java

@@ -191,11 +191,8 @@ public class FsUser extends BaseEntity
     @TableField(exist = false)
     private String nickname;
 
-    public String getNickname() {
-        return nickname;
-    }
-
-    public void setNickname(String nickname) {
-        this.nickname = nickname;
-    }
+    /**
+     * 用户余额
+     */
+    private BigDecimal money;
 }

+ 138 - 0
fs-service/src/main/java/com/fs/recharge/domain/RechargeTemplate.java

@@ -0,0 +1,138 @@
+package com.fs.recharge.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 充值模板实体类
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("recharge_template")
+public class RechargeTemplate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 模板ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 模板名称
+     */
+    private String templateName;
+
+    /**
+     * 储值金额
+     */
+    private BigDecimal rechargeAmount;
+
+    /**
+     * 赠送金额
+     */
+    private BigDecimal bonusAmount;
+
+    /**
+     * 关联优惠券ID列表,逗号分隔
+     */
+    private String couponIds;
+
+    /**
+     * 关联优惠券ID列表(非数据库字段)
+     */
+    @TableField(exist = false)
+    private List<Long> couponIdList;
+
+    /**
+     * 权益详情
+     */
+    private String benefitDetails;
+
+    /**
+     * 状态:0-禁用,1-启用
+     */
+    private Integer status;
+
+    /**
+     * 排序序号
+     */
+    private Integer sortOrder;
+
+    /**
+     * 有效期开始时间
+     */
+    private LocalDateTime startTime;
+
+    /**
+     * 有效期结束时间
+     */
+    private LocalDateTime endTime;
+
+    /**
+     * 适用用户类型:ALL-所有用户,NEW-新用户,OLD-老用户
+     */
+    private String userType;
+
+    /**
+     * 限购次数,0表示不限制
+     */
+    private Integer purchaseLimit;
+
+    /**
+     * 标签
+     */
+    private String tag;
+
+    /**
+     * 描述文案
+     */
+    private String shortDesc;
+
+    /**
+     * 详情链接
+     */
+    private String detailUrl;
+
+    /**
+     * 图标URL
+     */
+    private String iconUrl;
+
+    /**
+     * 是否默认选中:0-否,1-是
+     */
+    private Integer isDefault;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createdAt;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updatedAt;
+
+    /**
+     * 创建人ID
+     */
+    private Long createdBy;
+
+    /**
+     * 更新人ID
+     */
+    private Long updatedBy;
+}

+ 22 - 0
fs-service/src/main/java/com/fs/recharge/mapper/RechargeTemplateMapper.java

@@ -0,0 +1,22 @@
+package com.fs.recharge.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.recharge.domain.RechargeTemplate;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 充值模板Mapper接口
+ */
+@Mapper
+public interface RechargeTemplateMapper extends BaseMapper<RechargeTemplate> {
+
+    /**
+     * 查询有效的充值模板列表
+     * @param userType 用户类型
+     * @return 充值模板列表
+     */
+    List<RechargeTemplate> selectValidTemplates(@Param("userType") String userType);
+}

+ 49 - 0
fs-service/src/main/java/com/fs/recharge/service/RechargeTemplateService.java

@@ -0,0 +1,49 @@
+package com.fs.recharge.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.recharge.domain.RechargeTemplate;
+import com.fs.recharge.vo.RechargeTemplateVO;
+
+import java.util.List;
+
+/**
+ * 充值模板服务接口
+ */
+public interface RechargeTemplateService extends IService<RechargeTemplate> {
+
+    /**
+     * 获取可用的充值模板列表
+     * @param userType 用户类型
+     * @return 充值模板列表
+     */
+    List<RechargeTemplateVO> getValidTemplates(String userType);
+
+    /**
+     * 创建充值模板
+     * @param template 充值模板信息
+     * @return 创建结果
+     */
+    boolean createTemplate(RechargeTemplate template);
+
+    /**
+     * 更新充值模板
+     * @param template 充值模板信息
+     * @return 更新结果
+     */
+    boolean updateTemplate(RechargeTemplate template);
+
+    /**
+     * 启用或禁用充值模板
+     * @param id 模板ID
+     * @param status 状态:0-禁用,1-启用
+     * @return 操作结果
+     */
+    boolean updateStatus(Long id, Integer status);
+
+    /**
+     * 获取充值模板详情
+     * @param id 模板ID
+     * @return 充值模板详情
+     */
+    RechargeTemplateVO getTemplateDetail(Long id);
+}

+ 104 - 0
fs-service/src/main/java/com/fs/recharge/service/impl/RechargeTemplateServiceImpl.java

@@ -0,0 +1,104 @@
+package com.fs.recharge.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.recharge.domain.RechargeTemplate;
+import com.fs.recharge.mapper.RechargeTemplateMapper;
+import com.fs.recharge.service.RechargeTemplateService;
+import com.fs.recharge.vo.RechargeTemplateVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 充值模板服务实现类
+ */
+@Slf4j
+@Service
+public class RechargeTemplateServiceImpl extends ServiceImpl<RechargeTemplateMapper, RechargeTemplate> implements RechargeTemplateService {
+
+    @Override
+    public List<RechargeTemplateVO> getValidTemplates(String userType) {
+        List<RechargeTemplate> templates = baseMapper.selectValidTemplates(userType);
+        return templates.stream().map(this::convertToVO).collect(Collectors.toList());
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean createTemplate(RechargeTemplate template) {
+        // 处理优惠券ID列表
+        if (template.getCouponIdList() != null && !template.getCouponIdList().isEmpty()) {
+            template.setCouponIds(String.join(",", template.getCouponIdList().stream()
+                    .map(String::valueOf).collect(Collectors.toList())));
+        }
+
+        // 设置创建时间
+        template.setCreatedAt(LocalDateTime.now());
+        template.setUpdatedAt(LocalDateTime.now());
+
+        return save(template);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateTemplate(RechargeTemplate template) {
+        // 处理优惠券ID列表
+        if (template.getCouponIdList() != null && !template.getCouponIdList().isEmpty()) {
+            template.setCouponIds(String.join(",", template.getCouponIdList().stream()
+                    .map(String::valueOf).collect(Collectors.toList())));
+        }
+
+        // 设置更新时间
+        template.setUpdatedAt(LocalDateTime.now());
+
+        return updateById(template);
+    }
+
+    @Override
+    public boolean updateStatus(Long id, Integer status) {
+        LambdaUpdateWrapper<RechargeTemplate> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(RechargeTemplate::getId, id)
+                .set(RechargeTemplate::getStatus, status)
+                .set(RechargeTemplate::getUpdatedAt, LocalDateTime.now());
+
+        return update(updateWrapper);
+    }
+
+    @Override
+    public RechargeTemplateVO getTemplateDetail(Long id) {
+        RechargeTemplate template = getById(id);
+        if (template == null) {
+            return null;
+        }
+
+        return convertToVO(template);
+    }
+
+    /**
+     * 将实体对象转换为VO对象
+     */
+    private RechargeTemplateVO convertToVO(RechargeTemplate template) {
+        RechargeTemplateVO vo = new RechargeTemplateVO();
+        BeanUtils.copyProperties(template, vo);
+
+        // 处理优惠券ID列表
+        if (StringUtils.hasText(template.getCouponIds())) {
+            List<Long> couponIdList = Arrays.stream(template.getCouponIds().split(","))
+                    .map(Long::parseLong)
+                    .collect(Collectors.toList());
+            vo.setCouponIdList(couponIdList);
+        } else {
+            vo.setCouponIdList(new ArrayList<>());
+        }
+
+        return vo;
+    }
+}

+ 102 - 0
fs-service/src/main/java/com/fs/recharge/vo/RechargeTemplateVO.java

@@ -0,0 +1,102 @@
+package com.fs.recharge.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 充值模板VO对象
+ */
+@Data
+public class RechargeTemplateVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 模板ID
+     */
+    private Long id;
+
+    /**
+     * 模板名称
+     */
+    private String templateName;
+
+    /**
+     * 储值金额
+     */
+    private BigDecimal rechargeAmount;
+
+    /**
+     * 赠送金额
+     */
+    private BigDecimal bonusAmount;
+
+    /**
+     * 关联优惠券ID列表
+     */
+    private List<Long> couponIdList;
+
+    /**
+     * 权益详情
+     */
+    private String benefitDetails;
+
+    /**
+     * 状态:0-禁用,1-启用
+     */
+    private Integer status;
+
+    /**
+     * 排序序号
+     */
+    private Integer sortOrder;
+
+    /**
+     * 有效期开始时间
+     */
+    private LocalDateTime startTime;
+
+    /**
+     * 有效期结束时间
+     */
+    private LocalDateTime endTime;
+
+    /**
+     * 适用用户类型
+     */
+    private String userType;
+
+    /**
+     * 限购次数
+     */
+    private Integer purchaseLimit;
+
+    /**
+     * 标签
+     */
+    private String tag;
+
+    /**
+     * 描述文案
+     */
+    private String shortDesc;
+
+    /**
+     * 详情链接
+     */
+    private String detailUrl;
+
+    /**
+     * 图标URL
+     */
+    private String iconUrl;
+
+    /**
+     * 是否默认选中
+     */
+    private Integer isDefault;
+}

+ 153 - 0
fs-service/src/main/resources/application-druid-fby-test.yml

@@ -0,0 +1,153 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-fby,common
+    # redis 配置
+    redis:
+        # 地址
+        host: 127.0.0.1
+        # 端口,默认为6379
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 20s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 8
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+        #        clickhouse:
+        #            type: com.alibaba.druid.pool.DruidDataSource
+        #            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+        #            url: jdbc:clickhouse://cc-2vc8zzo26w0l7m2l6.public.clickhouse.ads.aliyuncs.com/sop?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+        #            username: rt_2024
+        #            password: Yzx_19860213
+        #            initialSize: 10
+        #            maxActive: 100
+        #            minIdle: 10
+        #            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://120.46.11.55:2345/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrztek250218!3@.
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://120.46.11.55:2345/sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrztek250218!3@.
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: rmq-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+    consumer:
+        group: test-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+openIM:
+    secret: openIM123
+    userID: imAdmin

+ 2 - 1
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -48,10 +48,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="courseMaOpenId"    column="course_ma_open_id"    />
         <result property="qwExtId"    column="qw_ext_id"    />
         <result property="qwUserId"    column="qw_user_id"    />
+        <result property="money"    column="money"    />
     </resultMap>
 
     <sql id="selectFsUserVo">
-        select user_id,qw_ext_id,sex,is_buy,course_ma_open_id,is_push,is_add_qw,source,login_device,is_individuation_push,store_open_id,password,jpush_id, is_vip,vip_start_date,vip_end_date,vip_level,vip_status,nick_name,integral_status, avatar, phone, integral,sign_num, status, tui_user_id, tui_time, tui_user_count, ma_open_id, mp_open_id, union_id, is_del, user_code, remark, create_time, update_time, last_ip, balance,is_weixin_auth,parent_id,qw_user_id,company_id,company_user_id from fs_user
+        select user_id,qw_ext_id,sex,is_buy,course_ma_open_id,is_push,is_add_qw,source,login_device,is_individuation_push,store_open_id,password,jpush_id, is_vip,vip_start_date,vip_end_date,vip_level,vip_status,nick_name,integral_status, avatar, phone, integral,sign_num, status, tui_user_id, tui_time, tui_user_count, ma_open_id, mp_open_id, union_id, is_del, user_code, remark, create_time, update_time, last_ip, balance,is_weixin_auth,parent_id,qw_user_id,company_id,company_user_id,money from fs_user
     </sql>
 
     <select id="selectFsUserList" parameterType="FsUser" resultMap="FsUserResult">

+ 40 - 0
fs-service/src/main/resources/mapper/recharge/RechargeTemplateMapper.xml

@@ -0,0 +1,40 @@
+<?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.fs.recharge.mapper.RechargeTemplateMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.fs.recharge.domain.RechargeTemplate">
+        <id column="id" property="id" />
+        <result column="template_name" property="templateName" />
+        <result column="recharge_amount" property="rechargeAmount" />
+        <result column="bonus_amount" property="bonusAmount" />
+        <result column="coupon_ids" property="couponIds" />
+        <result column="benefit_details" property="benefitDetails" />
+        <result column="status" property="status" />
+        <result column="sort_order" property="sortOrder" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="user_type" property="userType" />
+        <result column="purchase_limit" property="purchaseLimit" />
+        <result column="tag" property="tag" />
+        <result column="short_desc" property="shortDesc" />
+        <result column="detail_url" property="detailUrl" />
+        <result column="icon_url" property="iconUrl" />
+        <result column="is_default" property="isDefault" />
+        <result column="created_at" property="createdAt" />
+        <result column="updated_at" property="updatedAt" />
+        <result column="created_by" property="createdBy" />
+        <result column="updated_by" property="updatedBy" />
+    </resultMap>
+
+    <!-- 查询有效的充值模板列表 -->
+    <select id="selectValidTemplates" resultMap="BaseResultMap">
+        SELECT *
+        FROM recharge_template
+        WHERE status = 1
+          AND (start_time IS NULL OR start_time &lt;= NOW())
+          AND (end_time IS NULL OR end_time &gt;= NOW())
+          AND (user_type = 'ALL' OR user_type = #{userType})
+        ORDER BY sort_order ASC, id ASC
+    </select>
+</mapper>

+ 72 - 0
fs-user-app/src/main/java/com/fs/app/controller/RechargeTemplateController.java

@@ -0,0 +1,72 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.domain.R;
+import com.fs.recharge.domain.RechargeTemplate;
+import com.fs.recharge.service.RechargeTemplateService;
+import com.fs.recharge.vo.RechargeTemplateVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 充值模板控制器
+ */
+@Slf4j
+@Api(tags = "充值模板管理")
+@RestController
+@RequestMapping("/api/recharge-templates")
+public class RechargeTemplateController {
+
+    @Autowired
+    private RechargeTemplateService rechargeTemplateService;
+
+    @ApiOperation("获取可用的充值模板列表")
+    @GetMapping("/list")
+    public R getValidTemplates(
+            @ApiParam(value = "用户类型", required = false) @RequestParam(required = false, defaultValue = "ALL") String userType) {
+        List<RechargeTemplateVO> templates = rechargeTemplateService.getValidTemplates(userType);
+        return R.ok().put("data",templates);
+    }
+
+    @ApiOperation("获取充值模板详情")
+    @GetMapping("/{id}")
+    public R getTemplateDetail(
+            @ApiParam(value = "模板ID", required = true) @PathVariable Long id) {
+        RechargeTemplateVO template = rechargeTemplateService.getTemplateDetail(id);
+        if (template == null) {
+            return R.error("模板不存在");
+        }
+        return R.ok().put("data",template);
+    }
+
+    @ApiOperation("创建充值模板")
+    @PostMapping
+    public R createTemplate(@RequestBody RechargeTemplate template) {
+        boolean success = rechargeTemplateService.createTemplate(template);
+        return R.ok();
+    }
+
+    @ApiOperation("更新充值模板")
+    @PutMapping("/{id}")
+    public R updateTemplate(
+            @ApiParam(value = "模板ID", required = true) @PathVariable Long id,
+            @RequestBody RechargeTemplate template) {
+        template.setId(id);
+        boolean success = rechargeTemplateService.updateTemplate(template);
+        return R.ok();
+    }
+
+    @ApiOperation("启用或禁用充值模板")
+    @PutMapping("/{id}/status")
+    public R updateStatus(
+            @ApiParam(value = "模板ID", required = true) @PathVariable Long id,
+            @ApiParam(value = "状态:0-禁用,1-启用", required = true) @RequestParam Integer status) {
+        boolean success = rechargeTemplateService.updateStatus(id, status);
+        return R.ok();
+    }
+}