From deb91eb570baecdae92aeeb105661209f59e06e2 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期二, 01 四月 2025 14:23:46 +0800
Subject: [PATCH] Merge branch '2.0' of http://120.76.84.145:10101/gitblit/r/java/PlayPai into 2.0

---
 cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminAgreementController.java              |    3 
 cloud-server-activity/src/main/java/com/dsh/activity/model/response/SalesDetailVO.java                      |   37 +
 cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml                                         |  175 +++++++++
 cloud-server-activity/src/main/java/com/dsh/activity/entity/HuiminPayQuery.java                             |   39 ++
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/other/OperatorClient.java                  |    5 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/HuiminPayQuery.java         |   40 ++
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TPayHuiminController.java |  217 ++++++++--
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/AppUserClient.java                 |   10 
 cloud-server-management/src/main/webapp/static/modular/system/tPayHuimin/tPayHuimin.js                      |  123 +++++
 cloud-server-activity/src/main/java/com/dsh/activity/mapper/PayHuiminMapper.java                            |   26 +
 cloud-server-activity/src/main/java/com/dsh/activity/controller/PayHuiminController.java                    |   73 +++
 cloud-server-activity/src/main/java/com/dsh/activity/service/PayHuiminService.java                          |   34 +
 cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java                        |   51 ++
 cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminAgreementSetting.java                    |    2 
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java                 |    2 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/PayHuiminClient.java              |   36 +
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminAgreement/tHuiminAgreement.html          |    1 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tPayHuimin/tPayHuimin.html                      |  100 ++++
 cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java                 |  108 +++++
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SalesDetailVO.java                  |   37 +
 cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminCard.java                                |    6 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/THuiminCard.java            |    5 
 22 files changed, 1,028 insertions(+), 102 deletions(-)

diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
index c4a454e..ab51ce9 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
@@ -1,17 +1,33 @@
 package com.dsh.account.controller;
 
-import com.alibaba.nacos.common.utils.Md5Utils;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.dsh.account.dto.BindDto;
 import com.dsh.account.dto.IntroduceUserQuery;
 import com.dsh.account.dto.SelectDto;
 import com.dsh.account.dto.UpdateInfoDto;
-import com.dsh.account.entity.*;
-import com.dsh.account.model.*;
+import com.dsh.account.entity.IntroduceUser;
+import com.dsh.account.entity.TAppGift;
+import com.dsh.account.entity.TAppUser;
+import com.dsh.account.entity.TCourseInfoRecord;
+import com.dsh.account.entity.TStudent;
+import com.dsh.account.entity.UserIntegralChanges;
+import com.dsh.account.model.AddAppUserVo;
+import com.dsh.account.model.AdvertisementChangeStateDTO;
+import com.dsh.account.model.AppUserByNameAndPhoneDTO;
+import com.dsh.account.model.AppUserIdsByCityName;
+import com.dsh.account.model.JoinPlayPaiVo;
+import com.dsh.account.model.LoginSMSCodeVo;
+import com.dsh.account.model.LoginWeChatVo;
+import com.dsh.account.model.QueryByNamePhone;
 import com.dsh.account.model.query.appUserQuery.QueryAppUser;
 import com.dsh.account.model.vo.QueryAppUserVO;
-import com.dsh.account.service.*;
+import com.dsh.account.service.IVipPaymentService;
+import com.dsh.account.service.TAppGiftService;
+import com.dsh.account.service.TAppUserService;
+import com.dsh.account.service.TCourseInfoRecordService;
+import com.dsh.account.service.TStudentService;
+import com.dsh.account.service.UserIntegralChangesService;
 import com.dsh.account.util.PayMoneyUtil;
 import com.dsh.account.util.ResultUtil;
 import com.dsh.account.util.TokenUtil;
@@ -19,15 +35,22 @@
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
-import io.swagger.models.auth.In;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.PrintWriter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -503,7 +526,17 @@
             return null;
         }
     }
-
+    /**
+     * 根据用户id获取用户信息
+     *
+     * @param appUserIdList
+     * @return
+     */
+    @ResponseBody
+    @PostMapping("/base/appUser/queryAppUserBatch")
+    List<TAppUser> queryAppUserBatch(@RequestBody List<Integer> appUserIdList){
+        return appUserService.listByIds(appUserIdList);
+    }
 
     @Autowired
     private UserIntegralChangesService userIntegralChangesService;
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminAgreementController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminAgreementController.java
index 0e58ec6..f835ca2 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminAgreementController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminAgreementController.java
@@ -34,8 +34,7 @@
 
     /**
      * 根据当前用户类型查询惠民卡协议
-     * @param objectType
-     * @param operatorId
+     * @param query
      * @return
      */
     @ResponseBody
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PayHuiminController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PayHuiminController.java
new file mode 100644
index 0000000..80722a6
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PayHuiminController.java
@@ -0,0 +1,73 @@
+package com.dsh.activity.controller;
+
+import com.alipay.api.AlipayApiException;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.activity.entity.HuiminPayQuery;
+import com.dsh.activity.model.response.SalesDetailVO;
+import com.dsh.activity.service.PayHuiminService;
+import com.dsh.activity.util.ResultUtil;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 惠民卡支付记录
+ * @author mitao
+ * @date 2025/3/31
+ */
+@RestController
+@RequestMapping("")
+public class PayHuiminController {
+    @Resource
+    private PayHuiminService payHuiminService;
+
+    /**
+     * 售卖明细分页列表
+     * @param query
+     * @return
+     */
+    @PostMapping("/base/huimin-record/list")
+    public Page<SalesDetailVO> selectPage(@RequestBody HuiminPayQuery query){
+        return payHuiminService.selectPage(query);
+    }
+
+    /**
+     * 统计数据
+     * @param query
+     * @return
+     */
+    @PostMapping("/base/getStaticsData")
+    public Map<String, BigDecimal> getStaticsData(@RequestBody HuiminPayQuery query){
+        return payHuiminService.getStaticsData(query);
+    }
+    /**
+     * 退款惠民卡
+     * @param id
+     */
+    @GetMapping("/base/tPayHuimin/refund/{id}")
+    public ResultUtil<?> refund(@PathVariable("id") Integer id){
+        try {
+            return payHuiminService.refund(id);
+        } catch (AlipayApiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 导出数据
+     * @param query
+     * @return
+     */
+    @PostMapping("/base/tPayHuimin/export-data")
+    public List<SalesDetailVO> exportData(@RequestBody HuiminPayQuery query){
+        return payHuiminService.exportData(query);
+    }
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/HuiminPayQuery.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/HuiminPayQuery.java
new file mode 100644
index 0000000..3cae174
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/HuiminPayQuery.java
@@ -0,0 +1,39 @@
+package com.dsh.activity.entity;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class HuiminPayQuery {
+    // 基础查询条件
+    private String huiMinName;        // 惠民名称
+    private String huiMinType;        // 惠民类型
+    private Long operatorId;          // 运营商ID
+    private Long useId;               // 使用记录ID
+    
+    // 用户信息
+    private String userName;          // 用户名
+    private String phone;             // 联系方式
+    
+    // 时间范围
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date paymentTimeStart; // 支付时间-开始
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date paymentTimeEnd; // 支付时间-结束
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTimeStart;     // 结束时间-开始
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTimeEnd;     // 结束时间-结束
+
+    // 状态查询
+    private Integer status;     // 使用状态
+    //购买用户
+    private List<Integer> appUserIds;
+
+    private long current;
+    private long size;
+
+}
\ No newline at end of file
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminAgreementSetting.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminAgreementSetting.java
index 4f14fb0..4800e9c 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminAgreementSetting.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminAgreementSetting.java
@@ -33,8 +33,6 @@
      */
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
-    @TableField("agreementId")
-    private Integer agreementId;
     /**
      * 协议名称
      */
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminCard.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminCard.java
index 2111991..10896e4 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminCard.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/THuiminCard.java
@@ -164,6 +164,12 @@
     @TableField("storeId")
     private Integer storeId;
     /**
+     *运营商id
+     */
+    @ApiModelProperty(value = "运营商id")
+    @TableField("operatorId")
+    private Integer operatorId;
+    /**
      *状态 1已上架 2已下架 3已删除
      */
     @ApiModelProperty(value = "状态 1已上架 2已下架 3已删除 ")
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/AppUserClient.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/AppUserClient.java
index ca3c03b..62880dd 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/AppUserClient.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/AppUserClient.java
@@ -6,7 +6,6 @@
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.ResponseBody;
 
 import java.util.List;
 
@@ -32,4 +31,13 @@
      */
     @PostMapping("/base/appUser/queryAppUserList")
     public List<TAppUser> queryAppUserList(@RequestBody AppUserByNameAndPhoneDTO dto);
+
+    /**
+     * 根据用户id获取用户信息
+     *
+     * @param appUserIdList
+     * @return
+     */
+    @PostMapping("/base/appUser/queryAppUserBatch")
+    List<AppUser> queryAppUserBatch(@RequestBody List<Integer> appUserIdList);
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java
index 4d85c71..58ac733 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java
@@ -1,12 +1,10 @@
 package com.dsh.activity.feignclient.account;
 
 import com.dsh.activity.entity.TStudent;
-import com.dsh.activity.feignclient.account.model.Student;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
 
 import java.util.List;
 
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/other/OperatorClient.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/other/OperatorClient.java
index c7b98bc..01544a0 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/other/OperatorClient.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/other/OperatorClient.java
@@ -1,10 +1,9 @@
 package com.dsh.activity.feignclient.other;
 
-import com.dsh.activity.feignclient.other.model.Store;
-import com.dsh.activity.feignclient.other.model.StoreDetailOfCourse;
 import com.dsh.activity.feignclient.other.model.TOperatorCity;
 import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
 
 import java.util.List;
 
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/mapper/PayHuiminMapper.java b/cloud-server-activity/src/main/java/com/dsh/activity/mapper/PayHuiminMapper.java
index c2c01b5..c693d9a 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/mapper/PayHuiminMapper.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/mapper/PayHuiminMapper.java
@@ -1,17 +1,39 @@
 package com.dsh.activity.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.dsh.activity.entity.THuiminCard;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.activity.entity.HuiminPayQuery;
 import com.dsh.activity.entity.TPayHuimin;
-import com.dsh.activity.model.response.HuiminCardVO;
+import com.dsh.activity.model.response.SalesDetailVO;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author zhibing.pu
  * @date 2023/7/11 17:30
  */
 public interface PayHuiminMapper extends BaseMapper<TPayHuimin> {
+    /**
+     * 售卖明细分页列表
+     * @param query
+     * @return
+     */
+    Page<SalesDetailVO> selectSalesDetailPage(Page<SalesDetailVO> page,@Param("query") HuiminPayQuery query);
 
+    /**
+     * 获取售卖明细统计数据
+     * @param query
+     * @return
+     */
+    Map<String, BigDecimal> getStaticsData(@Param("query") HuiminPayQuery query);
+
+    /**
+     * 导出数据
+     * @param query
+     * @return
+     */
+    List<SalesDetailVO> exportData(@Param("query") HuiminPayQuery query);
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/model/response/SalesDetailVO.java b/cloud-server-activity/src/main/java/com/dsh/activity/model/response/SalesDetailVO.java
new file mode 100644
index 0000000..d218cdc
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/model/response/SalesDetailVO.java
@@ -0,0 +1,37 @@
+package com.dsh.activity.model.response;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class SalesDetailVO {
+    // 基础信息
+    private Long id;                    // 主键ID[8]
+    private String huiMinName;          // 惠民卡名称
+    private Integer huiMinType;          // 惠民卡类型(1:年度卡,2:年内卡)
+    private BigDecimal salesMoney;      // 售卖金额(精确计算)
+
+    // 关联信息
+    private Integer operatorId;
+    private String operatorName;        // 所属运营商
+    private Integer storeId;
+    private String storeName;           // 可用门店
+    private Integer appUserId;           // 购买用户ID
+    private String userName;            // 购买用户
+    private String phone;               // 联系电话
+
+    // 时间信息
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date paymentTime;  // 购买时间[1,8](@ref)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTime;      // 有效期
+
+    // 使用信息
+    private String studentName;         // 绑定人员
+    private String studentId;          // 绑定人员ID
+    private Integer useTimes;           // 已用次数
+    private Integer status;             // 状态(1:使用中,2:已退款)
+}
\ No newline at end of file
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/PayHuiminService.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/PayHuiminService.java
index 7e417fd..116f264 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/PayHuiminService.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/PayHuiminService.java
@@ -1,11 +1,16 @@
 package com.dsh.activity.service;
 
+import com.alipay.api.AlipayApiException;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.dsh.activity.entity.THuiminCard;
+import com.dsh.activity.entity.HuiminPayQuery;
 import com.dsh.activity.entity.TPayHuimin;
-import com.dsh.activity.model.response.HuiminCardVO;
+import com.dsh.activity.model.response.SalesDetailVO;
+import com.dsh.activity.util.ResultUtil;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -16,5 +21,30 @@
  * @since 2023-07-06
  */
 public interface PayHuiminService extends IService<TPayHuimin> {
+    /**
+     * 售卖明细分页列表
+     * @param query
+     * @return
+     */
+    Page<SalesDetailVO> selectPage(HuiminPayQuery query);
 
+    /**
+     * 获取统计数据
+     * @param query
+     * @return
+     */
+    Map<String, BigDecimal> getStaticsData(HuiminPayQuery query);
+
+    /**
+     * 退款惠民卡
+     * @param id
+     */
+    ResultUtil<?> refund(Integer id) throws AlipayApiException;
+
+    /**
+     * 获取导出数据
+     * @param query
+     * @return
+     */
+    List<SalesDetailVO> exportData(HuiminPayQuery query);
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java
index baa0086..481ac9f 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java
@@ -1,13 +1,33 @@
 package com.dsh.activity.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import com.alipay.api.AlipayApiException;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.dsh.activity.entity.THuiminAgreement;
+import com.dsh.activity.entity.HuiminPayQuery;
+import com.dsh.activity.entity.THuiminRecord;
 import com.dsh.activity.entity.TPayHuimin;
-import com.dsh.activity.mapper.HuiminAgreementMapper;
+import com.dsh.activity.entity.TStudent;
+import com.dsh.activity.feignclient.account.AppUserClient;
+import com.dsh.activity.feignclient.account.StudentClient;
+import com.dsh.activity.feignclient.account.model.AppUser;
 import com.dsh.activity.mapper.PayHuiminMapper;
-import com.dsh.activity.service.HuiminAgreementService;
+import com.dsh.activity.model.response.SalesDetailVO;
+import com.dsh.activity.service.HuiminRecordService;
 import com.dsh.activity.service.PayHuiminService;
+import com.dsh.activity.util.DateUtil;
+import com.dsh.activity.util.PayMoneyUtil;
+import com.dsh.activity.util.ResultUtil;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * @author zhibing.pu
@@ -15,5 +35,87 @@
  */
 @Service
 public class PayHuiminServiceImpl extends ServiceImpl<PayHuiminMapper, TPayHuimin> implements PayHuiminService {
+    @Autowired
+    private AppUserClient appUserClient;
+    @Autowired
+    private StudentClient studentClient;
+    @Autowired
+    private HuiminRecordService huiminRecordService;
+    @Resource
+    private PayMoneyUtil payMoneyUtil;
+    @Override
+    public Page<SalesDetailVO> selectPage(HuiminPayQuery query) {
+        Page<SalesDetailVO> salesDetailVOPage = baseMapper.selectSalesDetailPage(new Page<>(query.getCurrent(), query.getSize()), query);
+        List<SalesDetailVO> records = salesDetailVOPage.getRecords();
+        if (CollUtil.isNotEmpty(records)){
+            List<Integer> appUserIdList = records.stream().map(SalesDetailVO::getAppUserId).collect(Collectors.toList());
+            List<AppUser> appUserList = appUserClient.queryAppUserBatch(appUserIdList);
+            Map<Integer, AppUser> appUserMap = appUserList.stream().collect(Collectors.toMap(AppUser::getId, appUser -> appUser));
+            records.forEach(item->{
+                AppUser appUser = appUserMap.get(item.getAppUserId());
+                if (Objects.nonNull(appUser)){
+                    item.setUserName(appUser.getName());
+                    item.setPhone(appUser.getPhone());
+                }
+                List<TStudent> studentList = studentClient.getStudentByIds(item.getStudentId());
+                if (CollUtil.isNotEmpty(studentList)){
+                    item.setStudentName(studentList.stream().map(TStudent::getName).collect(Collectors.joining(",")));
+                }
+            });
+        }
+        return salesDetailVOPage;
+    }
 
+    @Override
+    public Map<String, BigDecimal> getStaticsData(HuiminPayQuery query) {
+        return baseMapper.getStaticsData(query);
+    }
+
+    @Override
+    public ResultUtil<?> refund(Integer id) throws AlipayApiException {
+        TPayHuimin payHuimin = this.getById(id);
+        if (Objects.nonNull(payHuimin)) {
+            Integer count = huiminRecordService.lambdaQuery().eq(THuiminRecord::getAppUserId, payHuimin.getAppUserId())
+                    .eq(THuiminRecord::getHuiminCardId, payHuimin.getCardId())
+                    .lt(THuiminRecord::getInsertTime, DateUtil.addDay(payHuimin.getPaymentTime(),7))
+                    .count();
+            if (count > 0 || new Date().after(DateUtil.addDay(payHuimin.getPaymentTime(),7))) {
+                //超过七日或者七日内有使用记录的退款:更改状态,实际退款线下操作。
+                payHuimin.setRefundStatus(3);
+            } else {
+                if (payHuimin.getPaymentType() == 1) {
+                    Map<String, String> map = payMoneyUtil.wxRefund(payHuimin.getOrderNumber(), payHuimin.getCode(),
+                            payHuimin.getSalesMoney().toString(), payHuimin.getSalesMoney().toString(), "/base/worldCup/wxRefundWorldCupCallback");
+                    if (!"SUCCESS".equals(map.get("return_code"))) {
+                        System.err.println("-------------微信退款失败---------");
+                        System.err.println(map.get("return_msg"));
+                        return ResultUtil.error("微信退款失败");
+                    }
+                } else {
+                    Map<String, String> map = payMoneyUtil.aliRefund(payHuimin.getOrderNumber(), payHuimin.getSalesMoney().toString());
+                    String return_code = map.get("code");
+                    if (!"10000".equals(return_code)) {
+                        return ResultUtil.error(map.get("msg"));
+                    }
+                    String refund_id = map.get("trade_no");
+                    payHuimin.setRefundNumber(refund_id);
+                }
+                payHuimin.setRefundStatus(2);
+            }
+            payHuimin.setStatus(3);
+            payHuimin.setRefundTime(new Date());
+            this.updateById(payHuimin);
+        }
+        return ResultUtil.success();
+    }
+
+    /**
+     * 导出数据
+     * @param query
+     * @return
+     */
+    @Override
+    public List<SalesDetailVO> exportData(HuiminPayQuery query) {
+        return baseMapper.exportData(query);
+    }
 }
diff --git a/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml b/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml
index 39d32f1..41def9f 100644
--- a/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml
@@ -3,5 +3,180 @@
 <mapper namespace="com.dsh.activity.mapper.PayHuiminMapper">
 
 
+    <select id="selectSalesDetailPage" resultType="com.dsh.activity.model.response.SalesDetailVO">
+        SELECT
+        tph.id,
+        thc.huiMinName,
+        thc.huiMinType,
+        thc.salesMoney,
+        thc.operatorId,
+        thc.storeId,
+        tph.appUserId,
+        tph.paymentTime,
+        thc.endTime,
+        tph.studentId,
+        tph.status,
+        CASE
+        WHEN tph.id IS NULL THEN NULL
+        ELSE COALESCE(COUNT(thr.id), 0)
+        END AS useTimes
+        FROM
+        t_pay_huimin tph
+        LEFT JOIN t_huimin_card thc ON tph.cardId = thc.id
+        LEFT JOIN t_huimin_record thr ON tph.appUserId= thr.appUserId AND tph.cardId= thr.huiminCardId
+        <where>
+            tph.id IS NOT NULL
+            <if test="query.huiMinName !=null and query.huiMinName != ''">
+                AND thc.huiMinName LIKE CONCAT('%',#{query.huiMinName},'%')
+            </if>
+            <if test="query.huiMinType !=null and query.huiMinType != ''">
+                AND thc.huiMinType = #{query.huiMinType}
+            </if>
+            <if test="query.operatorId !=null and query.operatorId != ''">
+                AND thc.huiMinType = #{query.huiMinType}
+            </if>
+            <if test="query.useId !=null and query.useId != ''">
+                AND FIND_IN_SET(#{query.useId},thc.useIds)
+            </if>
+            <if test="query.useId !=null and query.useId != ''">
+                AND FIND_IN_SET(#{query.useId},thc.useIds)
+            </if>
+            <if test="query.appUserIds != null and query.appUserIds.size()>0">
+                AND tph.appUserId IN
+                <foreach collection="query.appUserIds" item="appUserId" open="(" separator="," close=")">
+                    #{appUserId}
+                </foreach>
+            </if>
+            <if test="query.paymentTimeStart != null and query.paymentTimeEnd!=null">
+                AND tph.paymentTime BETWEEN #{query.paymentTimeStart} AND #{query.paymentTimeEnd}
+            </if>
+            <if test="query.endTimeStart != null and query.endTimeEnd!=null">
+                AND tph.endTime BETWEEN #{query.endTimeStart} AND #{query.endTimeEnd}
+            </if>
+            <if test="query.status!=null and query.status !=''">
+                <choose>
+                    <when test="query.status == 1">
+                        AND tph.status = 2
+                    </when>
+                    <when test="query.status == 2">
+                        AND tph.status = 3
+                    </when>
+                </choose>
+            </if>
+        </where>
+        ORDER BY tph.insertTime DESC
+    </select>
+    <select id="getStaticsData" resultType="java.util.Map"
+            parameterType="com.dsh.activity.entity.HuiminPayQuery">
+        SELECT
+        COALESCE(SUM( tph.salesMoney),0) AS totalAmount,
+        COALESCE(SUM(CASE WHEN refundStatus IN (2, 3) THEN tph.salesMoney ELSE 0 END),0) AS refundAmount
+        FROM t_pay_huimin tph
+        LEFT JOIN t_huimin_card thc ON tph.cardId = thc.id
+        <where>
+            tph.id IS NOT NULL
+            <if test="query.huiMinName !=null and query.huiMinName != ''">
+                AND thc.huiMinName LIKE CONCAT('%',#{query.huiMinName},'%')
+            </if>
+            <if test="query.huiMinType !=null and query.huiMinType != ''">
+                AND thc.huiMinType = #{query.huiMinType}
+            </if>
+            <if test="query.operatorId !=null and query.operatorId != ''">
+                AND thc.huiMinType = #{query.huiMinType}
+            </if>
+            <if test="query.useId !=null and query.useId != ''">
+                AND FIND_IN_SET(#{query.useId},thc.useIds)
+            </if>
+            <if test="query.useId !=null and query.useId != ''">
+                AND FIND_IN_SET(#{query.useId},thc.useIds)
+            </if>
+            <if test="query.appUserIds != null and query.appUserIds.size()>0">
+                AND tph.appUserId IN
+                <foreach collection="query.appUserIds" item="appUserId" open="(" separator="," close=")">
+                    #{appUserId}
+                </foreach>
+            </if>
+            <if test="query.paymentTimeStart != null and query.paymentTimeEnd!=null">
+                AND tph.paymentTime BETWEEN #{query.paymentTimeStart} AND #{query.paymentTimeEnd}
+            </if>
+            <if test="query.endTimeStart != null and query.endTimeEnd!=null">
+                AND tph.endTime BETWEEN #{query.endTimeStart} AND #{query.endTimeEnd}
+            </if>
+            <if test="query.status!=null and query.status !=''">
+                <choose>
+                    <when test="query.status == 1">
+                        AND tph.status = 2
+                    </when>
+                    <when test="query.status == 2">
+                        AND tph.status = 3
+                    </when>
+                </choose>
+            </if>
+        </where>
+    </select>
 
+    <select id="exportData" resultType="com.dsh.activity.model.response.SalesDetailVO"
+            parameterType="com.dsh.activity.entity.HuiminPayQuery">
+        SELECT
+        tph.id,
+        thc.huiMinName,
+        thc.huiMinType,
+        thc.salesMoney,
+        thc.operatorId,
+        thc.storeId,
+        tph.appUserId,
+        tph.paymentTime,
+        thc.endTime,
+        tph.studentId,
+        tph.status,
+        CASE
+        WHEN tph.id IS NULL THEN NULL
+        ELSE COALESCE(COUNT(thr.id), 0)
+        END AS useTimes
+        FROM
+        t_pay_huimin tph
+        LEFT JOIN t_huimin_card thc ON tph.cardId = thc.id
+        LEFT JOIN t_huimin_record thr ON tph.appUserId= thr.appUserId AND tph.cardId= thr.huiminCardId
+        <where>
+             tph.id IS NOT NULL
+            <if test="query.huiMinName !=null and query.huiMinName != ''">
+                AND thc.huiMinName LIKE CONCAT('%',#{query.huiMinName},'%')
+            </if>
+            <if test="query.huiMinType !=null and query.huiMinType != ''">
+                AND thc.huiMinType = #{query.huiMinType}
+            </if>
+            <if test="query.operatorId !=null and query.operatorId != ''">
+                AND thc.huiMinType = #{query.huiMinType}
+            </if>
+            <if test="query.useId !=null and query.useId != ''">
+                AND FIND_IN_SET(#{query.useId},thc.useIds)
+            </if>
+            <if test="query.useId !=null and query.useId != ''">
+                AND FIND_IN_SET(#{query.useId},thc.useIds)
+            </if>
+            <if test="query.appUserIds != null and query.appUserIds.size()>0">
+                AND tph.appUserId IN
+                <foreach collection="query.appUserIds" item="appUserId" open="(" separator="," close=")">
+                    #{appUserId}
+                </foreach>
+            </if>
+            <if test="query.paymentTimeStart != null and query.paymentTimeEnd!=null">
+                AND tph.paymentTime BETWEEN #{query.paymentTimeStart} AND #{query.paymentTimeEnd}
+            </if>
+            <if test="query.endTimeStart != null and query.endTimeEnd!=null">
+                AND tph.endTime BETWEEN #{query.endTimeStart} AND #{query.endTimeEnd}
+            </if>
+            <if test="query.status!=null and query.status !=''">
+                <choose>
+                    <when test="query.status == 1">
+                        AND tph.status = 2
+                    </when>
+                    <when test="query.status == 2">
+                        AND tph.status = 3
+                    </when>
+                </choose>
+            </if>
+        </where>
+        ORDER BY tph.insertTime DESC
+    </select>
 </mapper>
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/PayHuiminClient.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/PayHuiminClient.java
index 4080339..2a96015 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/PayHuiminClient.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/PayHuiminClient.java
@@ -1,6 +1,17 @@
 package com.dsh.course.feignClient.activity;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.course.feignClient.activity.model.HuiminPayQuery;
+import com.dsh.guns.modular.system.model.SalesDetailVO;
+import com.dsh.guns.modular.system.util.ResultUtil;
 import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author mitao
@@ -8,4 +19,29 @@
  */
 @FeignClient(value = "mb-cloud-activity")
 public interface PayHuiminClient {
+    /**
+     * 获取售卖明细
+     * @param query
+     * @return
+     */
+    @PostMapping("/base/huimin-record/list")
+    Page<SalesDetailVO> selectPage(@RequestBody HuiminPayQuery query);
+
+    /**
+     * 获取售卖明细统计数据
+     * @param query
+     * @return
+     */
+    @PostMapping("/base/getStaticsData")
+    Map<String, BigDecimal> getStaticsData(@RequestBody HuiminPayQuery query);
+
+    /**
+     * 退款惠民卡
+     * @param id
+     */
+    @GetMapping("/base/tPayHuimin/refund/{id}")
+    ResultUtil<?> refund(Integer id);
+
+    @PostMapping("/base/tPayHuimin/export-data")
+    List<SalesDetailVO> exportData(@RequestBody HuiminPayQuery query);
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/HuiminPayQuery.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/HuiminPayQuery.java
new file mode 100644
index 0000000..1b04018
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/HuiminPayQuery.java
@@ -0,0 +1,40 @@
+package com.dsh.course.feignClient.activity.model;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class HuiminPayQuery {
+    // 基础查询条件
+    private String huiMinName;        // 惠民名称
+    private String huiMinType;        // 惠民类型
+    private Long operatorId;          // 运营商ID
+    private Long useId;               // 使用记录ID
+    
+    // 用户信息
+    private String userName;          // 用户名
+    private String phone;             // 联系方式
+    
+    // 时间范围
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date paymentTimeStart; // 支付时间-开始
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date paymentTimeEnd; // 支付时间-结束
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTimeStart;     // 结束时间-开始
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTimeEnd;     // 结束时间-结束
+
+    // 状态查询
+    private Integer status;     // 使用状态
+
+    //购买用户
+    private List<Integer> appUserIds;
+
+    private long current;
+    private long size;
+
+}
\ No newline at end of file
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/THuiminCard.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/THuiminCard.java
index 0ad8a8f..d50b289 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/THuiminCard.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/THuiminCard.java
@@ -129,6 +129,11 @@
      */
     @TableField("storeId")
     private Integer storeId;
+    /**
+     *运营商id
+     */
+    @TableField("operatorId")
+    private Integer operatorId;
 
 
     @Override
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TPayHuiminController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TPayHuiminController.java
index 28f8e6b..0d2f20b 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TPayHuiminController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TPayHuiminController.java
@@ -1,10 +1,44 @@
 package com.dsh.guns.modular.system.controller.code;
 
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.course.feignClient.account.AppUserClient;
+import com.dsh.course.feignClient.account.model.TAppUser;
 import com.dsh.course.feignClient.activity.PayHuiminClient;
+import com.dsh.course.feignClient.activity.model.HuiminPayQuery;
+import com.dsh.course.feignClient.activity.model.TPayHuimin;
 import com.dsh.guns.core.base.controller.BaseController;
+import com.dsh.guns.core.common.constant.factory.PageFactory;
+import com.dsh.guns.modular.system.model.AppUserByNameAndPhoneDTO;
+import com.dsh.guns.modular.system.model.SalesDetailVO;
+import com.dsh.guns.modular.system.model.TOperator;
+import com.dsh.guns.modular.system.model.TStore;
+import com.dsh.guns.modular.system.service.IStoreService;
+import com.dsh.guns.modular.system.service.TOperatorService;
+import com.dsh.guns.modular.system.util.DateUtil;
+import com.dsh.guns.modular.system.util.ExcelUtil;
+import com.dsh.guns.modular.system.util.ResultUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * 惠民卡控制器
@@ -20,12 +54,22 @@
 
     @Autowired
     private PayHuiminClient payHuiminClient;
+    @Autowired
+    private TOperatorService operatorService;
+    @Autowired
+    private IStoreService storeService;
+    @Autowired
+    private AppUserClient appUserClient;
+
 
     /**
      * 跳转到惠民卡首页
      */
     @RequestMapping("")
-    public String index() {
+    public String index(Model model) {
+        //查询运营商列表
+        model.addAttribute("operatorList", operatorService.list(new QueryWrapper<TOperator>().eq("state", 1)));
+        model.addAttribute("storeList", storeService.list(new QueryWrapper<TStore>().eq("state", 1)));
         return PREFIX + "tPayHuimin.html";
     }
 
@@ -37,62 +81,141 @@
         return PREFIX + "tPayHuimin_add.html";
     }
 
-  /*  *//**
-     * 跳转到修改惠民卡
-     *//*
-    @RequestMapping("/tPayHuimin_update/{tPayHuiminId}")
-    public String tPayHuiminUpdate(@PathVariable Integer tPayHuiminId, Model model) {
-        TPayHuimin tPayHuimin = payHuiminClient.selectById(tPayHuiminId);
-        model.addAttribute("item",tPayHuimin);
-        LogObjectHolder.me().set(tPayHuimin);
-        return PREFIX + "tPayHuimin_edit.html";
-    }
-
-    *//**
+    /**
      * 获取惠民卡列表
-     *//*
+     */
     @RequestMapping(value = "/list")
     @ResponseBody
-    public Object list(String condition) {
-        return payHuiminClient.selectList(null);
+    public Object list(HuiminPayQuery query) {
+        Page<TPayHuimin> tPayHuiminPage = new PageFactory<TPayHuimin>().defaultPage();
+        query.setCurrent(tPayHuiminPage.getCurrent());
+        query.setSize(tPayHuiminPage.getSize());
+        List<Integer> appUserIds = Collections.emptyList();
+        if (StringUtils.isNotBlank(query.getUserName()) || StringUtils.isNotBlank(query.getPhone())){
+            AppUserByNameAndPhoneDTO appUserByNameAndPhoneDTO = new AppUserByNameAndPhoneDTO();
+            appUserByNameAndPhoneDTO.setUserName(query.getUserName());
+            appUserByNameAndPhoneDTO.setPhone(query.getPhone());
+            List<TAppUser> tAppUsers = appUserClient.queryAPPUserByNameAndPhone(appUserByNameAndPhoneDTO);
+            appUserIds = tAppUsers.stream()
+                    .map(TAppUser::getId)
+                    .collect(Collectors.toList());
+            if (CollUtil.isEmpty(appUserIds)){
+                return new Page<>();
+            }
+        }
+        query.setAppUserIds(appUserIds);
+        Page<SalesDetailVO> salesDetailVOPage = payHuiminClient.selectPage(query);
+        List<SalesDetailVO> records = salesDetailVOPage.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            List<Integer> operatorIdList = records.stream()
+                    .map(SalesDetailVO::getOperatorId)
+                    .collect(Collectors.toList());
+            List<Integer> storeIdList = records.stream()
+                    .map(SalesDetailVO::getStoreId)
+                    .collect(Collectors.toList());
+            Map<Integer, String> operatorMap = operatorService.listByIds(operatorIdList).stream()
+                    .collect(Collectors.toMap(TOperator::getId, TOperator::getName));
+            Map<Integer, String> storeMap = storeService.listByIds(storeIdList).stream()
+                    .collect(Collectors.toMap(TStore::getId, TStore::getName));
+            records.forEach(item->{
+                item.setOperatorName(operatorMap.getOrDefault(item.getOperatorId(),""));
+                item.setStoreName(storeMap.getOrDefault(item.getStoreId(),""));
+            });
+        }
+        return super.packForBT(salesDetailVOPage);
     }
 
-    *//**
-     * 新增惠民卡
-     *//*
-    @RequestMapping(value = "/add")
+    /**
+     * 获取统计数据
+     * @param query
+     * @return
+     */
+    @RequestMapping("/getStaticsData")
     @ResponseBody
-    public Object add(TPayHuimin tPayHuimin) {
-        payHuiminClient.insert(tPayHuimin);
-        return SUCCESS_TIP;
+    public ResultUtil<Map<String, BigDecimal>> getStaticsData(HuiminPayQuery query) {
+        Map<String, BigDecimal> map = new HashMap<>();
+        map.put("totalAmount",BigDecimal.ZERO);
+        map.put("refundAmount",BigDecimal.ZERO);
+        List<Integer> appUserIds = Collections.emptyList();
+        if (StringUtils.isNotBlank(query.getUserName()) || StringUtils.isNotBlank(query.getPhone())){
+            AppUserByNameAndPhoneDTO appUserByNameAndPhoneDTO = new AppUserByNameAndPhoneDTO();
+            appUserByNameAndPhoneDTO.setUserName(query.getUserName());
+            appUserByNameAndPhoneDTO.setPhone(query.getPhone());
+            List<TAppUser> tAppUsers = appUserClient.queryAPPUserByNameAndPhone(appUserByNameAndPhoneDTO);
+            appUserIds = tAppUsers.stream()
+                    .map(TAppUser::getId)
+                    .collect(Collectors.toList());
+            if (CollUtil.isEmpty(appUserIds)){
+                return ResultUtil.success(map);
+            }
+        }
+        query.setAppUserIds(appUserIds);
+        map =  payHuiminClient.getStaticsData(query);
+        return ResultUtil.success(map);
     }
 
-    *//**
-     * 删除惠民卡
-     *//*
-    @RequestMapping(value = "/delete")
+    /**
+     * 退款
+     * @param id
+     * @return
+     */
+    @GetMapping("/refund/{id}")
     @ResponseBody
-    public Object delete(@RequestParam Integer tPayHuiminId) {
-        payHuiminClient.deleteById(tPayHuiminId);
-        return SUCCESS_TIP;
+    public ResultUtil<?> refund(@PathVariable("id") Integer id) {
+        return payHuiminClient.refund(id);
     }
 
-    *//**
-     * 修改惠民卡
-     *//*
-    @RequestMapping(value = "/update")
-    @ResponseBody
-    public Object update(TPayHuimin tPayHuimin) {
-        payHuiminClient.updateById(tPayHuimin);
-        return SUCCESS_TIP;
+    /**
+     * 导出售卖明细
+     * @param query
+     */
+    @GetMapping("/export")
+    public void exportData(HuiminPayQuery query, HttpServletResponse response) {
+        List<SalesDetailVO> records = payHuiminClient.exportData(query);
+        records = records.stream().filter(Objects::nonNull).collect(Collectors.toList());
+        if (CollUtil.isNotEmpty(records)) {
+            List<Integer> operatorIdList = records.stream()
+                    .map(SalesDetailVO::getOperatorId)
+                    .collect(Collectors.toList());
+            List<Integer> storeIdList = records.stream()
+                    .map(SalesDetailVO::getStoreId)
+                    .collect(Collectors.toList());
+            Map<Integer, String> operatorMap = operatorService.listByIds(operatorIdList).stream()
+                    .collect(Collectors.toMap(TOperator::getId, TOperator::getName));
+            Map<Integer, String> storeMap = storeService.listByIds(storeIdList).stream()
+                    .collect(Collectors.toMap(TStore::getId, TStore::getName));
+            records.forEach(item -> {
+                item.setOperatorName(operatorMap.getOrDefault(item.getOperatorId(), ""));
+                item.setStoreName(storeMap.getOrDefault(item.getStoreId(), ""));
+            });
+        }
+        String[] titleArr = {"惠民卡名称", "惠民卡类型", "售卖金额", "所属运营商", "可用门店", "购买用户", "联系电话", "购买时间", "绑定人员", "已用次数", "有效期", "状态"};
+        String[][] values = new String[records.size()][];
+        for (int i = 0; i < records.size(); i++) {
+            SalesDetailVO salesDetailVO = records.get(i);
+            values[i] = new String[titleArr.length];
+            values[i][0] = salesDetailVO.getHuiMinName();
+            values[i][1] = salesDetailVO.getHuiMinType() == 1 ? "年度卡" : "年内卡";
+            values[i][2] = salesDetailVO.getSalesMoney().toString();
+            values[i][3] = salesDetailVO.getOperatorName();
+            values[i][4] = salesDetailVO.getStoreName();
+            values[i][5] = salesDetailVO.getUserName();
+            values[i][6] = salesDetailVO.getPhone();
+            values[i][7] = DateUtil.format(salesDetailVO.getPaymentTime(), "yyyy-MM-dd HH:mm:ss");
+            values[i][8] = salesDetailVO.getStudentName();
+            values[i][9] = salesDetailVO.getUseTimes().toString();
+            values[i][10] = DateUtil.format(salesDetailVO.getEndTime(), "yyyy-MM-dd HH:mm:ss");
+            values[i][11] = salesDetailVO.getStatus() == 2 ? "使用中" : "已退款";
+        }
+        try {
+            HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook("售卖明细", titleArr, values, null);
+            ExcelUtil.setResponseHeader(response, "售卖明细.xls");
+            OutputStream os = response.getOutputStream();
+            wb.write(os);
+            os.flush();
+            os.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
     }
-
-    *//**
-     * 惠民卡详情
-     *//*
-    @RequestMapping(value = "/detail/{tPayHuiminId}")
-    @ResponseBody
-    public Object detail(@PathVariable("tPayHuiminId") Integer tPayHuiminId) {
-        return payHuiminClient.selectById(tPayHuiminId);
-    }*/
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SalesDetailVO.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SalesDetailVO.java
new file mode 100644
index 0000000..ecfc282
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SalesDetailVO.java
@@ -0,0 +1,37 @@
+package com.dsh.guns.modular.system.model;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class SalesDetailVO {
+    // 基础信息
+    private Long id;                    // 主键ID[8]
+    private String huiMinName;          // 惠民卡名称
+    private Integer huiMinType;          // 惠民卡类型(1:年度卡,2:年内卡)
+    private BigDecimal salesMoney;      // 售卖金额(精确计算)
+    
+    // 关联信息
+    private Integer operatorId;
+    private String operatorName;        // 所属运营商
+    private Integer storeId;
+    private String storeName;           // 可用门店
+    private Integer appUserId;           // 购买用户ID
+    private String userName;            // 购买用户
+    private String phone;               // 联系电话
+    
+    // 时间信息
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date paymentTime;  // 购买时间[1,8](@ref)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTime;      // 有效期
+    
+    // 使用信息
+    private String studentName;         // 绑定人员
+    private String studentId;          // 绑定人员ID
+    private Integer useTimes;           // 已用次数
+    private Integer status;             // 状态(1:使用中,2:已退款)
+}
\ No newline at end of file
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminAgreement/tHuiminAgreement.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminAgreement/tHuiminAgreement.html
index 42c31f1..7bbd8a5 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminAgreement/tHuiminAgreement.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminAgreement/tHuiminAgreement.html
@@ -27,6 +27,7 @@
                                 <#button name="删除" icon="fa-remove" clickFun="THuiminAgreement.delete()" space="true"/>
                             @}
                         </div>
+
                         <#table id="THuiminAgreementTable"/>
                     </div>
                 </div>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tPayHuimin/tPayHuimin.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tPayHuimin/tPayHuimin.html
index fc699e8..37c091c 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tPayHuimin/tPayHuimin.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tPayHuimin/tPayHuimin.html
@@ -3,36 +3,114 @@
     <div class="col-sm-12">
         <div class="ibox float-e-margins">
             <div class="ibox-title">
-                <h5>惠民卡管理</h5>
+                <h5>售卖明细</h5>
             </div>
             <div class="ibox-content">
                 <div class="row row-lg">
                     <div class="col-sm-12">
                         <div class="row">
-                            <div class="col-sm-3">
-                                <#NameCon id="condition" name="名称" />
+                            <div class="form-group">
+                                <div class="col-sm-3">
+                                    <#NameCon id="huiMinName" name="惠民卡名称:" />
+                                </div>
+                                <div class="col-sm-3">
+                                    <#SelectCon id="huiMinType" name="惠民卡类型:">
+                                        <option value="">全部</option>
+                                        <option value="1">年度卡</option>
+                                        <option value="2">年内卡</option>
+                                    </#SelectCon>
+                                </div>
+                                <div class="col-sm-3">
+                                    <#SelectCon id="operatorId" name="所属运营商:">
+                                        <option value="">全部</option>
+                                        @if(isNotEmpty(operatorList)){
+                                            @for(item in operatorList){
+                                                <option value="${item.id}">${item.name}</option>
+                                            @}
+                                        @}
+                                    </#SelectCon>
+                                </div>
+                                <div class="col-sm-3">
+                                    <#SelectCon id="useId" name="可用门店:">
+                                        <option value="">全部</option>
+                                        @if(isNotEmpty(storeList)){
+                                        @for(item in storeList){
+                                        <option value="${item.id}">${item.name}</option>
+                                        @}
+                                        @}
+                                    </#SelectCon>
+                                </div>
                             </div>
+                            <div class="form-group">
+                                <div class="col-sm-3">
+                                    <#NameCon id="userName" name="购买用户:" />
+                                </div>
+                                <div class="col-sm-3">
+                                    <#NameCon id="phone" name="联系电话:" />
+                                </div>
+                                <div class="col-sm-3">
+                                    <#TimeCon id="paymentTimeStr" name="购买时间:" />
+                                </div>
+                                <div class="col-sm-3">
+                                    <#TimeCon id="endTimeStr" name="有效期至:" />
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <div class="col-sm-3">
+                                    <#SelectCon id="status" name="使用状态:">
+                                        <option value="">全部</option>
+                                        <option value="1">使用中</option>
+                                        <option value="2">已退款</option>
+                                    </#SelectCon>
+                                </div>
                             <div class="col-sm-3">
                                 <#button name="搜索" icon="fa-search" clickFun="TPayHuimin.search()"/>
+                                <#button name="重置" icon="fa-search" clickFun="TPayHuimin.resetSearch()"/>
                             </div>
+                            </div>
+
                         </div>
                         <div class="hidden-xs" id="TPayHuiminTableToolbar" role="group">
-                            @if(shiro.hasPermission("/tPayHuimin/add")){
-                                <#button name="添加" icon="fa-plus" clickFun="TPayHuimin.openAddTPayHuimin()"/>
+                            @if(shiro.hasPermission("/tPayHuimin/refund")){
+                                <#button name="退款" icon="fa-plus" clickFun="TPayHuimin.refund()"/>
                             @}
-                            @if(shiro.hasPermission("/tPayHuimin/update")){
-                                <#button name="修改" icon="fa-edit" clickFun="TPayHuimin.openTPayHuiminDetail()" space="true"/>
+                            @if(shiro.hasPermission("/tPayHuimin/export")){
+                                <#button name="导出" icon="fa-edit" clickFun="TPayHuimin.export()" space="true"/>
                             @}
-                            @if(shiro.hasPermission("/tPayHuimin/delete")){
-                                <#button name="删除" icon="fa-remove" clickFun="TPayHuimin.delete()" space="true"/>
-                            @}
+                            <div class="form-group">
+                                <label> 售卖总金额:¥</label>
+                                <label id="totalAmount">0</label>&emsp;&emsp;
+                                <label>已退款金额:¥</label>
+                                <label id="refundAmount">0</label>
+                            </div>
                         </div>
                         <#table id="TPayHuiminTable"/>
+
                     </div>
                 </div>
             </div>
         </div>
     </div>
 </div>
-<script src="${ctxPath}/static/modular/system/tPayHuimin/tPayHuimin.js"></script>
+
+<script src="${ctxPath}/modular/system/tPayHuimin/tPayHuimin.js"></script>
+<script>
+    //日期范围选择
+    laydate.render({
+        elem: '#paymentTimeStr',
+        type: 'date'
+        ,range: '~' //或 range: '~' 来自定义分割字符
+        ,trigger:'click'
+    });
+    //日期范围选择
+    laydate.render({
+        elem: '#endTimeStr',
+        type: 'date'
+        ,range: '~' //或 range: '~' 来自定义分割字符
+        ,trigger:'click'
+    });
+    $(function () {
+
+    });
+</script>
 @}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tPayHuimin/tPayHuimin.js b/cloud-server-management/src/main/webapp/static/modular/system/tPayHuimin/tPayHuimin.js
index da437a4..1c00185 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tPayHuimin/tPayHuimin.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tPayHuimin/tPayHuimin.js
@@ -14,20 +14,25 @@
 TPayHuimin.initColumn = function () {
     return [
         {field: 'selectItem', radio: true},
-            {title: '主键id', field: 'id', visible: true, align: 'center', valign: 'middle'},
-            {title: '金额', field: 'salesMoney', visible: true, align: 'center', valign: 'middle'},
-            {title: '购买用户id', field: 'appUserId', visible: true, align: 'center', valign: 'middle'},
-            {title: '绑定人员id,多个逗号拼接,关联student表', field: 'studentId', visible: true, align: 'center', valign: 'middle'},
+            {title: '主键id', field: 'id', visible: false, align: 'center', valign: 'middle'},
+            {title: '惠民卡名称', field: 'huiMinName', visible: true, align: 'center', valign: 'middle'},
+            {title: '惠民卡类型', field: 'huiMinType', visible: true, align: 'center', valign: 'middle',
+                formatter:function(value,row,index){
+                    return {1: '年度卡', 2: '年内卡'}[value];
+                }},
+            {title: '售卖金额', field: 'salesMoney', visible: true, align: 'center', valign: 'middle'},
+            {title: '所属运营商', field: 'operatorName', visible: true, align: 'center', valign: 'middle'},
+            {title: '可用门店', field: 'storeName', visible: true, align: 'center', valign: 'middle'},
+            {title: '购买用户', field: 'userName', visible: true, align: 'center', valign: 'middle'},
+            {title: '联系电话', field: 'phone', visible: true, align: 'center', valign: 'middle'},
+            {title: '购买时间', field: 'paymentTime', visible: true, align: 'center', valign: 'middle'},
+            {title: '绑定人员', field: 'studentName', visible: true, align: 'center', valign: 'middle'},
+            {title: '已用次数', field: 'useTimes', visible: true, align: 'center', valign: 'middle'},
             {title: '有效期', field: 'endTime', visible: true, align: 'center', valign: 'middle'},
-            {title: '状态1使用中2已退款', field: 'status', visible: true, align: 'center', valign: 'middle'},
-            {title: '创建时间', field: 'insertTime', visible: true, align: 'center', valign: 'middle'},
-            {title: '付款时间', field: 'paymentTime', visible: true, align: 'center', valign: 'middle'},
-            {title: '付款方式1微信2支付宝', field: 'paymentType', visible: true, align: 'center', valign: 'middle'},
-            {title: '订单号', field: 'code', visible: true, align: 'center', valign: 'middle'},
-            {title: '第三方支付流水号', field: 'orderNumber', visible: true, align: 'center', valign: 'middle'},
-            {title: '退款时间', field: 'refundTime', visible: true, align: 'center', valign: 'middle'},
-            {title: '退款状态 1未退款 2已退款 3线下退款(使用过或超过七日退款)', field: 'refundStatus', visible: true, align: 'center', valign: 'middle'},
-            {title: '惠民卡id', field: 'cardId', visible: true, align: 'center', valign: 'middle'}
+            {title: '状态', field: 'status', visible: true, align: 'center', valign: 'middle',
+                formatter:function(value,row,index){
+                    return {1: '使用中', 2: '已退款'}[value];
+                }}
     ];
 };
 
@@ -92,19 +97,101 @@
         ajax.start();
     }
 };
-
+TPayHuimin.getStaticsData = function (){
+    var queryData = TPayHuimin.getQueryParam();
+    //提交信息
+    var ajax = new $ax(Feng.ctxPath + "/tPayHuimin/getStaticsData", function(data){
+        if (data.data!=null && data.data !=''){
+            $('#totalAmount').text(data.data.totalAmount);
+            $('#refundAmount').text(data.data.refundAmount);
+        }
+    },function(data){
+        Feng.error("获取统计数据失败!" + data.responseJSON.message + "!");
+    });
+    ajax.setData(queryData);
+    ajax.start();
+}
+TPayHuimin.refund = function (){
+    if (this.check()) {
+        if (TPayHuimin.seItem.refundStatus != 1){
+            Feng.error("该商品已退款");
+            return;
+        }
+        let operation = function(){
+            let ajax = new $ax(Feng.ctxPath + "/tPayHuimin/refund", function () {
+                Feng.success("退款成功!");
+                TPayHuimin.table.refresh();
+            }, function (data) {
+                Feng.error("退款失败!" + data.responseJSON.message + "!");
+            });
+            ajax.set("id", TPayHuimin.seItem.id);
+            ajax.start();
+        };
+        Feng.confirm("确认退款所选惠民卡吗?",operation);
+    }
+}
+TPayHuimin.export = function (){
+    var queryData = TPayHuimin.getQueryParam();
+    // 生成带参数的完整URL
+    var exportUrl = Feng.ctxPath + "/tPayHuimin/export?" + $.param(queryData);
+    window.location.href = exportUrl;
+}
+/**
+ * 获取查询参数
+ * @returns {{}}
+ */
+TPayHuimin.getQueryParam = function () {
+    var queryData = {};
+    queryData['huiMinName'] = $("#huiMinName").val();
+    queryData['huiMinType'] = $("#huiMinType").val();
+    queryData['operatorId'] = $("#operatorId").val();
+    queryData['useId'] = $("#useId").val();
+    queryData['userName'] = $("#userName").val();
+    queryData['phone'] = $("#phone").val();
+    let paymentTimeStr = $("#paymentTimeStr").val();
+    if (paymentTimeStr){
+        queryData['paymentTimeStart'] = paymentTimeStr.split('~')[0]+' 00:00:00';
+        queryData['paymentTimeEnd'] = paymentTimeStr.split('~')[1]+' 23:59:59';
+    }
+    let endTimeStr = $("#endTimeStr").val();
+    if (endTimeStr){
+        queryData['endTimeStart'] = endTimeStr.split('~')[0]+' 00:00:00';
+        queryData['endTimeEnd'] = endTimeStr.split('~')[1]+' 23:59:59';
+    }
+    queryData['status'] = $("#status").val();
+    //过滤空值
+    Object.keys(queryData).forEach(key => {
+        if (queryData[key] === null || queryData[key] === '') {
+            delete queryData[key];
+        }
+    });
+    return queryData;
+}
 /**
  * 查询惠民卡列表
  */
 TPayHuimin.search = function () {
-    var queryData = {};
-    queryData['condition'] = $("#condition").val();
+    var queryData = TPayHuimin.getQueryParam();
     TPayHuimin.table.refresh({query: queryData});
+    TPayHuimin.getStaticsData();
 };
-
+TPayHuimin.resetSearch = function () {
+    var queryData = {};
+    $("#huiMinName").val('');
+    $("#huiMinType option:first").prop("selected", true);
+    $("#operatorId option:first").prop("selected", true);
+    $("#useId option:first").prop("selected", true);
+    $("#userName").val('');
+    $("#phone").val('');
+    $("#paymentTimeStr").val('');
+    $("#endTimeStr").val('');
+    $("#status option:first").prop("selected", true);
+    TPayHuimin.search();
+};
 $(function () {
     var defaultColunms = TPayHuimin.initColumn();
     var table = new BSTable(TPayHuimin.id, "/tPayHuimin/list", defaultColunms);
-    table.setPaginationType("client");
+    table.setPaginationType("server");
     TPayHuimin.table = table.init();
+    TPayHuimin.getStaticsData();
 });

--
Gitblit v1.7.1