From 572df690f72ed4a077d934823f261dec39b3cc7d Mon Sep 17 00:00:00 2001
From: 刘帅 <rr.iii@qq.com>
Date: 星期二, 08 九月 2026 17:11:34 +0800
Subject: [PATCH] feat&bug:文档内容修改

---
 cloud-server-management/src/main/webapp/WEB-INF/view/system/ball/yuyue.html                                         |    1 
 cloud-server-management/src/main/webapp/static/modular/system/tAuditRecord/tAuditRecord.js                          |    6 
 cloud-server-competition/src/main/resources/mapper/ParticipantMapper.xml                                            |    5 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/HuiminPayQuery.java                 |    5 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition.html                     |    4 
 cloud-server-activity/src/main/resources/mapper/IntroduceUserMapper.xml                                             |    1 
 cloud-server-management/src/main/webapp/static/modular/system/tUserRedPacketRecord/tUserRedPacketRecord.js          |    6 
 cloud-server-management/src/main/webapp/static/modular/system/tPayHuimin/tPayHuimin.js                              |   14 
 sql/playpai_other.sql                                                                                               |   10 
 cloud-server-other/src/main/java/com/dsh/config/MyLocaleResolver.java                                               |    6 
 cloud-server-management/src/main/webapp/static/modular/system/ball/ball.js                                          |    6 
 cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment.js           |    2 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html                                    |    2 
 cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java                          |    9 
 cloud-server-account/src/main/java/com/dsh/account/feignclient/competition/model/PaymentCompetition.java            |    4 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/CompetitionQuery.java            |    2 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TStoredValueConfigController.java |   58 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java                        |   39 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TPayHuimin.java                     |    2 
 cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos.js                           |    2 
 cloud-server-management/src/main/webapp/static/modular/system/tSmsrecord/tSmsrecord.js                              |    6 
 cloud-server-auth/src/main/java/cn/mb/cloud/auth/controller/UserController.java                                     |   53 
 cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOther.js                                   |    8 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/operatorIncome.html                      |   63 
 cloud-server-management/src/main/webapp/static/modular/system/userCouponRecord/userCouponRecord.js                  |    6 
 cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherTwo.js                                |    5 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/RegisterOrderVO.java                        |    2 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html                   |    4 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelUtil.java                               |   21 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TAppUserController.java           |    1 
 cloud-server-management/src/main/resources/mapper/MenuMapper.xml                                                    |    1 
 cloud-server-activity/src/main/resources/mapper/IntroduceRewardsMapper.xml                                          |    1 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TNoticController.java             |    4 
 cloud-server-management/src/main/webapp/static/modular/system/tSite/tSiteLock.js                                    |   31 
 cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java                         |   13 
 cloud-server-account/src/main/java/com/dsh/account/entity/VipPayment.java                                           |    3 
 cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherOne.js                                |    5 
 cloud-server-account/src/main/resources/mapper/UserIntegralChangesMapper.xml                                        |    1 
 cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_edit.js                      |    2 
 cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent.js                                  |    6 
 cloud-server-management/src/main/webapp/static/modular/system/user/user.js                                          |   21 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TFinanceController.java           |  146 +-
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TPayHuiminController.java         |   25 
 cloud-server-management/src/main/webapp/static/modular/system/driverActivityHistory/driverActivityHistory.js        |    6 
 cloud-server-management/src/main/webapp/static/modular/system/tFeedback/tFeedback.js                                |    6 
 cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java                                |   27 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/PermissionsFilter.java                                |    4 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_edit.html                                   |    2 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_add.html                                      |   11 
 cloud-server-account/src/main/resources/mapper/UserAuditMapper.xml                                                  |    1 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition.html                          |    4 
 cloud-server-activity/src/main/resources/mapper/BodySideAppointmentsMapper.xml                                      |    3 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user.html                                          |    3 
 cloud-server-management/src/main/webapp/static/modular/system/tQuestion/TQuestion.js                                |    2 
 cloud-server-course/src/main/resources/mapper/CancelledClassesMapper.xml                                            |    1 
 cloud-server-account/src/main/resources/mapper/TAppUserMapper.xml                                                   |   12 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java       |   48 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java                           |   14 
 cloud-server-other/src/main/resources/mapper/SiteBookingMapper.xml                                                  |    6 
 cloud-server-other/src/main/java/com/dsh/other/controller/TPhoneController.java                                     |    4 
 cloud-server-activity/src/main/java/com/dsh/activity/service/impl/HuiminCardServiceImpl.java                        |  107 +
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_add.html                 |    8 
 cloud-server-management/src/main/webapp/static/modular/system/tAgreement/tAgreement.js                              |    6 
 cloud-server-account/src/main/resources/mapper/CoachMapper.xml                                                      |    1 
 cloud-server-management/src/main/webapp/static/modular/system/sysCouponRecord/sysCouponRecord.js                    |    6 
 cloud-server-activity/src/main/java/com/dsh/activity/model/response/SalesDetailVO.java                              |    7 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html                     |   15 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TicketController.java             |  121 ++
 cloud-server-activity/src/main/java/com/dsh/activity/service/UserCouponService.java                                 |   10 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelExportUtil.java                         |   12 
 cloud-server-other/src/main/java/com/dsh/other/model/SiteBookingQuery.java                                          |    2 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeQuery.java                            |    2 
 cloud-server-management/src/main/webapp/static/modular/system/tFeedback/userFeedback.js                             |    6 
 cloud-server-activity/src/main/java/com/dsh/activity/service/HuiminCardService.java                                 |    8 
 cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java                                         |    2 
 cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition_info.js                |   10 
 cloud-server-management/src/main/webapp/static/modular/system/tGoods/tPay_info.js                                   |   38 
 cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition.js                          |    8 
 cloud-server-management/src/main/resources/mapper/UserMapper.xml                                                    |   34 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SalesDetailVO.java                          |    7 
 cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition.js                     |   10 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_edit.html                                     |   21 
 cloud-server-management/src/main/webapp/static/modular/system/userActivity/userActivity.js                          |    6 
 cloud-server-activity/src/main/java/com/dsh/activity/model/WriteOffDTO.java                                         |    5 
 cloud-server-account/src/main/java/com/dsh/account/model/IncomeQuery.java                                           |    2 
 cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml                                                 |   21 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/PaymentCompetition.java          |    5 
 cloud-server-activity/src/main/java/com/dsh/activity/entity/HuiminPayQuery.java                                     |    5 
 cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java                 |  103 +
 cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent_commite.js                          |    6 
 cloud-server-management/src/main/webapp/static/modular/system/benefits/TBenefits.js                                 |    2 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TSiteServiceImpl.java                |   13 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/WriteOffDTO.java                    |    5 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/DataStatisticsController.java     |  521 +++++----
 cloud-server-other/src/main/java/com/dsh/other/controller/BallController.java                                       |    4 
 cloud-server-management/src/main/webapp/static/modular/system/tEnsureIncomeRule/tEnsureIncomeRule.js                |    6 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html                      |   14 
 cloud-server-management/src/main/webapp/static/modular/system/sysRedPacketRecord/sysRedPacketRecord.js              |    6 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeVO.java                               |    4 
 cloud-server-other/src/main/java/com/dsh/OtherApplication.java                                                      |    2 
 cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java                                    |   54 -
 cloud-server-account/src/main/resources/mapper/RechargeRecordsMapper.xml                                            |   11 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/BallController.java             |  183 +++
 cloud-server-course/src/main/java/com/dsh/course/model/RegisterOrderVO.java                                         |    2 
 cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_add.js                       |    2 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_edit.html                |   10 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/account/model/VipPayment.java                      |    2 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java          |  139 ++
 cloud-server-management/src/main/webapp/static/modular/system/tHuiminRecord/tHuiminRecord.js                        |    6 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_one.html                           |    2 
 cloud-server-account/src/main/java/com/dsh/account/controller/FinanceController.java                                |    1 
 cloud-server-activity/src/main/java/com/dsh/activity/service/impl/UserCouponServiceImpl.java                        |   64 +
 cloud-server-course/src/main/resources/mapper/TCoursePackageDiscountMapper.xml                                      |    2 
 cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java                                |   77 +
 cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java                                       |   93 +
 cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment_edit.js      |    2 
 cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue_info.js                                    |    9 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java              |   31 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser.html                                   |    3 
 cloud-server-activity/src/main/resources/mapper/UserCouponMapper.xml                                                |    1 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/CouponClient.java                         |   13 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_payOne.html                               |   18 
 cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info_one.js                               |   34 
 cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java                           |    5 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/account/AppUserClient.java                         |    5 
 cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js                     |   24 
 cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js                           |    4 
 cloud-server-management/src/main/webapp/static/modular/system/appUser/tAppUser.js                                   |   32 
 cloud-server-competition/src/main/resources/mapper/PaymentCompetitionMapper.xml                                     |   17 
 cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info.js                                   |   57 
 cloud-server-other/src/main/java/com/dsh/other/controller/TVipController.java                                       |    6 
 cloud-server-activity/src/main/java/com/dsh/activity/entity/UserPointsMerchandise.java                              |    5 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java                               |   10 
 cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionQuery.java                              |    2 
 cloud-server-management/src/main/java/com/dsh/course/mapper/UserMapper.java                                         |    8 
 cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue.js                                         |   42 
 cloud-server-management/src/main/webapp/static/modular/system/tUserExit/tbUserExit.js                               |    3 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SiteBookingQuery.java                       |    2 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponPaymentController.java                    |   10 
 cloud-server-management/src/main/webapp/static/modular/system/tHuiminAgreement/tHuiminAgreement.js                  |    6 
 cloud-server-management/src/main/webapp/static/modular/system/user/user_info.js                                     |   19 
 cloud-server-management/src/main/webapp/static/modular/system/driverActivity/driverActivity.js                      |    6 
 cloud-server-activity/src/main/resources/mapper/UserPointsMerchandiseMapper.xml                                     |    5 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/transfer/UserDto.java                             |    6 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java                          |   48 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/worldCup/worldCup.html                                  |    2 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/platformIncome.html                      |   99 +
 cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java                    |   75 -
 cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser_edit.html                              |    2 
 149 files changed, 2,311 insertions(+), 885 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 a75c076..279e705 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
@@ -39,6 +39,7 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RequestHeader;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -243,6 +244,28 @@
     public TAppUser queryAppUser1(@RequestBody Integer appUserId) {
         TAppUser appUser = appUserService.getById(appUserId);
         return appUser;
+    }
+
+    /**
+     * Internal-only data source for the management sensitive-data query.  The
+     * caller is authenticated and authorised by the management service; its
+     * Feign interceptor adds the header that permits the response to remain
+     * unmasked for that single request.
+     */
+    @PostMapping("/internal/sensitive/app-user/{id}")
+    public Map<String, Object> sensitiveAppUser(@PathVariable("id") Integer id,
+                                                @RequestHeader(value = "X-Internal-Sensitive-Access", required = false) String access) {
+        if (!"true".equalsIgnoreCase(access)) {
+            throw new IllegalStateException("Sensitive data access is restricted to the management service");
+        }
+        TAppUser user = appUserService.getById(id);
+        if (user == null) return null;
+        Map<String, Object> result = new java.util.HashMap<String, Object>();
+        result.put("id", user.getId());
+        result.put("name", user.getName());
+        result.put("phone", user.getPhone());
+        result.put("idCard", user.getIdCard());
+        return result;
     }
 
     /**
@@ -842,6 +865,10 @@
     public void updateAppUser(@RequestBody TAppUser appUser) {
         try {
             TAppUser appUser1 = appUserService.getById(appUser.getId());
+            // A management edit form may contain the displayed masked value.
+            // Never persist that display value over the original identifier.
+            if (appUser.getPhone() != null && appUser.getPhone().contains("*")) appUser.setPhone(appUser1.getPhone());
+            if (appUser.getIdCard() != null && appUser.getIdCard().contains("*")) appUser.setIdCard(appUser1.getIdCard());
             appUserService.updateById(appUser);
             if (appUser.getIntegral().compareTo(appUser1.getIntegral()) != 0) {
                 UserIntegralChanges userIntegralChanges = new UserIntegralChanges();
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/FinanceController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/FinanceController.java
index bf0e37a..c7d732a 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/FinanceController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/FinanceController.java
@@ -111,6 +111,7 @@
         vipPayment.setRemark(vipRefundDto.getRemark());
         appUserService.updateById(appUser);
         vipPayment.setPayStatus(3);
+        vipPayment.setRefundTime(new Date());
         vipPaymentService.updateById(vipPayment);
         // 将未使用的门票优惠券设置为已过期
         userConponClient.setStatusVipDetail(vipPayment.getId());
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java
index e33eafd..0f07197 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java
@@ -57,6 +57,22 @@
     private CoursePackageClient coursePackageClient;
 
     /**
+     * 注销账号保留业务记录,但不计入后台累计用户、累计学员统计。
+     */
+    private List<Integer> getActiveUserIds(List<Integer> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return Collections.singletonList(-1);
+        }
+        List<Integer> activeUserIds = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                        .in(TAppUser::getId, ids)
+                        .ne(TAppUser::getState, 3))
+                .stream()
+                .map(TAppUser::getId)
+                .collect(Collectors.toList());
+        return activeUserIds.isEmpty() ? Collections.singletonList(-1) : activeUserIds;
+    }
+
+    /**
      * 查询玩湃惠民卡绑定学员列表信息
      *
      * @return
@@ -353,35 +369,49 @@
         if (ids.size() == 0) {
             ids.add(-1);
         }
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 1));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 1)
+                .ne(TAppUser::getState, 3));
         return list.stream().map(TAppUser::getId).collect(Collectors.toList());
     }
 
     @PostMapping("/student/getUserYYs")
     @ResponseBody
     public List<Integer> getUserYYs(@RequestBody Integer id) {
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 2).eq(TAppUser::getAddUserId, id));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 2)
+                .eq(TAppUser::getAddUserId, id)
+                .ne(TAppUser::getState, 3));
         return list.stream().map(TAppUser::getId).collect(Collectors.toList());
     }
 
     @PostMapping("/student/getUserStore")
     @ResponseBody
     public List<Integer> getUserStore(@RequestBody Integer id) {
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 3).eq(TAppUser::getAddUserId, id));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 3)
+                .eq(TAppUser::getAddUserId, id)
+                .ne(TAppUser::getState, 3));
         return list.stream().map(TAppUser::getId).collect(Collectors.toList());
     }
 
     @PostMapping("/student/getUserYys")
     @ResponseBody
     public List<Integer> getUserYys(@RequestBody Integer id) {
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 2).eq(TAppUser::getAddUserId, id));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 2)
+                .eq(TAppUser::getAddUserId, id)
+                .ne(TAppUser::getState, 3));
         return list.stream().map(TAppUser::getId).collect(Collectors.toList());
     }
 
     @ResponseBody
     @PostMapping("/student/getUserPtVip")
     public List<Integer> getUserPtVip() {
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 1).eq(TAppUser::getIsVip, 1));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 1)
+                .eq(TAppUser::getIsVip, 1)
+                .ne(TAppUser::getState, 3));
         return list.stream().map(TAppUser::getId).collect(Collectors.toList());
     }
 
@@ -391,9 +421,14 @@
     public HashMap<String, Object> userAndVipPt(@RequestBody Integer type) {
         HashMap<String, Object> map = new HashMap<>();
         // 所有的
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 1));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 1)
+                .ne(TAppUser::getState, 3));
         map.put("allUser", list.size());
-        List<TAppUser> list1 = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 1).eq(TAppUser::getIsVip, 1));
+        List<TAppUser> list1 = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 1)
+                .eq(TAppUser::getIsVip, 1)
+                .ne(TAppUser::getState, 3));
         map.put("allVip", list1.size());
 
 
@@ -500,7 +535,9 @@
     public HashMap<String, Object> stuPt() {
         HashMap<String, Object> map = new HashMap<>();
         // 所有的
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().eq(TAppUser::getInsertType, 1));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .eq(TAppUser::getInsertType, 1)
+                .ne(TAppUser::getState, 3));
         List<Integer> collect1 = list.stream().map(TAppUser::getId).collect(Collectors.toList());
         if (collect1.size() == 0) {
             collect1.add(-1);
@@ -593,7 +630,8 @@
     @PostMapping("/student/stuYys")
     public HashMap<String, Object> stuYys(@RequestBody List<Integer> ids) {
         HashMap<String, Object> map = new HashMap<>();
-        List<TStudent> students = studentService.list(new LambdaQueryWrapper<TStudent>().in(TStudent::getAppUserId, ids));
+        List<Integer> activeUserIds = getActiveUserIds(ids);
+        List<TStudent> students = studentService.list(new LambdaQueryWrapper<TStudent>().in(TStudent::getAppUserId, activeUserIds));
         map.put("allUser", students.size());
 
         ArrayList<Object> integers = new ArrayList<>();
@@ -697,7 +735,8 @@
     public HashMap<String, Object> stuStores(@RequestBody List<Integer> ids) {
         HashMap<String, Object> map = new HashMap<>();
 
-        List<TStudent> students = studentService.list(new LambdaQueryWrapper<TStudent>().in(TStudent::getAppUserId, ids));
+        List<Integer> activeUserIds = getActiveUserIds(ids);
+        List<TStudent> students = studentService.list(new LambdaQueryWrapper<TStudent>().in(TStudent::getAppUserId, activeUserIds));
         map.put("allUser", students.size());
 
         ArrayList<Object> integers = new ArrayList<>();
@@ -799,9 +838,14 @@
         HashMap<String, Object> map = new HashMap<>();
 
         // 所有的
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().in(TAppUser::getId, ids));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .in(TAppUser::getId, ids)
+                .ne(TAppUser::getState, 3));
         map.put("allUser", list.size());
-        List<TAppUser> list1 = appUserService.list(new LambdaQueryWrapper<TAppUser>().in(TAppUser::getId, ids).eq(TAppUser::getIsVip, 1));
+        List<TAppUser> list1 = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .in(TAppUser::getId, ids)
+                .eq(TAppUser::getIsVip, 1)
+                .ne(TAppUser::getState, 3));
         map.put("allVip", list1.size());
 
 
@@ -907,9 +951,14 @@
     public HashMap<String, Object> userAndVipStore(@RequestBody List<Integer> ids) {
         HashMap<String, Object> map = new HashMap<>();
         // 所有的
-        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>().in(TAppUser::getId, ids));
+        List<TAppUser> list = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .in(TAppUser::getId, ids)
+                .ne(TAppUser::getState, 3));
         map.put("allUser", list.size());
-        List<TAppUser> list1 = appUserService.list(new LambdaQueryWrapper<TAppUser>().in(TAppUser::getId, ids).eq(TAppUser::getIsVip, 1));
+        List<TAppUser> list1 = appUserService.list(new LambdaQueryWrapper<TAppUser>()
+                .in(TAppUser::getId, ids)
+                .eq(TAppUser::getIsVip, 1)
+                .ne(TAppUser::getState, 3));
         map.put("allVip", list1.size());
 
 
diff --git a/cloud-server-account/src/main/java/com/dsh/account/entity/VipPayment.java b/cloud-server-account/src/main/java/com/dsh/account/entity/VipPayment.java
index 7f6ad32..5484053 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/entity/VipPayment.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/entity/VipPayment.java
@@ -89,6 +89,9 @@
      */
     @TableField("remark")
     private String remark;
+    /** 退款完成时间。 */
+    @TableField("refundTime")
+    private Date refundTime;
 
 
     public static String CODE() {
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/competition/model/PaymentCompetition.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/competition/model/PaymentCompetition.java
index 359de61..cf8b955 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/competition/model/PaymentCompetition.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/competition/model/PaymentCompetition.java
@@ -23,6 +23,10 @@
      */
     private Integer competitionId;
     /**
+     * 下单时活动举办门店 ID 列表快照。
+     */
+    private String competitionStoreIds;
+    /**
      * 用户id
      */
     private Integer appUserId;
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/IncomeQuery.java b/cloud-server-account/src/main/java/com/dsh/account/model/IncomeQuery.java
index 6a56c86..879de51 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/IncomeQuery.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/IncomeQuery.java
@@ -21,4 +21,6 @@
     // 用户ids
     private List<Integer> userIds;
     private Integer insertType;
+    /** 是否包含已退款订单,用于统计支付与退款两条事实流水。 */
+    private Boolean includeRefund;
 }
diff --git a/cloud-server-account/src/main/resources/mapper/CoachMapper.xml b/cloud-server-account/src/main/resources/mapper/CoachMapper.xml
index 0e0879e..4f94b46 100644
--- a/cloud-server-account/src/main/resources/mapper/CoachMapper.xml
+++ b/cloud-server-account/src/main/resources/mapper/CoachMapper.xml
@@ -40,5 +40,6 @@
             </if>
             and t1.state != 3
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
 </mapper>
diff --git a/cloud-server-account/src/main/resources/mapper/RechargeRecordsMapper.xml b/cloud-server-account/src/main/resources/mapper/RechargeRecordsMapper.xml
index 6630cb7..51ce7d6 100644
--- a/cloud-server-account/src/main/resources/mapper/RechargeRecordsMapper.xml
+++ b/cloud-server-account/src/main/resources/mapper/RechargeRecordsMapper.xml
@@ -33,6 +33,7 @@
             </if>
             and t1.payStatus = 2
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
     <select id="listAll" resultType="com.dsh.account.entity.VipPayment">
         select t1.* from t_vip_payment t1
@@ -53,7 +54,15 @@
             <if test="sTime !=null and sTime!= '' and eTime !=null and eTime!= ''">
                 and t1.insertTime between #{sTime} and #{eTime}
             </if>
-            and t1.payStatus = 2
+            <choose>
+                <when test="query.includeRefund != null and query.includeRefund">
+                    and t1.payStatus IN (2, 3)
+                </when>
+                <otherwise>
+                    and t1.payStatus = 2
+                </otherwise>
+            </choose>
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
 </mapper>
diff --git a/cloud-server-account/src/main/resources/mapper/TAppUserMapper.xml b/cloud-server-account/src/main/resources/mapper/TAppUserMapper.xml
index 3e06e1f..d87c0de 100644
--- a/cloud-server-account/src/main/resources/mapper/TAppUserMapper.xml
+++ b/cloud-server-account/src/main/resources/mapper/TAppUserMapper.xml
@@ -71,8 +71,8 @@
                     #{id}
                 </foreach>
             </if>
-            and t1.state != 3
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
     <select id="getSelects" resultType="com.dsh.account.dto.SelectDto">
         SELECT ts.id ,ts.`name` as value
@@ -100,6 +100,7 @@
     <select id="getYearUserCount" resultType="com.dsh.account.vo.entity.YearData">
         select IFNULL(count(*),0) AS yearCount,DATE_FORMAT(insertTime,'%Y') AS `year` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.cityCode != null and dto.cityCode != ''">
                 AND cityCode = #{dto.cityCode}
             </if>
@@ -120,6 +121,7 @@
     <select id="getMonthUserCount" resultType="com.dsh.account.vo.entity.MonthData">
         select IFNULL(count(*),0) AS monthCount,DATE_FORMAT(insertTime,'%Y%m') AS `month` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.cityCode != null and dto.cityCode != ''">
                 AND cityCode = #{dto.cityCode}
             </if>
@@ -140,6 +142,7 @@
     <select id="getWeekUserCount4" resultType="com.dsh.account.vo.entity.WeekData">
         select IFNULL(count(*),0) AS weekCount,4 AS `week` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.startTime != null and dto.startTime != '' and dto.endTime != null and dto.endTime != ''">
                 AND insertTime between #{dto.startTime} and #{dto.endTime}
             </if>
@@ -163,6 +166,7 @@
     <select id="getWeekUserCount3" resultType="com.dsh.account.vo.entity.WeekData">
         select IFNULL(count(*),0) AS weekCount,3 AS `week` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.startTime != null and dto.startTime != '' and dto.endTime != null and dto.endTime != ''">
                 AND insertTime between #{dto.startTime} and #{dto.endTime}
             </if>
@@ -186,6 +190,7 @@
     <select id="getWeekUserCount2" resultType="com.dsh.account.vo.entity.WeekData">
         select IFNULL(count(*),0) AS weekCount,2 AS `week` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.startTime != null and dto.startTime != '' and dto.endTime != null and dto.endTime != ''">
                 AND insertTime between #{dto.startTime} and #{dto.endTime}
             </if>
@@ -209,6 +214,7 @@
     <select id="getWeekUserCount1" resultType="com.dsh.account.vo.entity.WeekData">
         select IFNULL(count(*),0) AS weekCount,1 AS `week` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.startTime != null and dto.startTime != '' and dto.endTime != null and dto.endTime != ''">
                 AND insertTime between #{dto.startTime} and #{dto.endTime}
             </if>
@@ -232,6 +238,7 @@
     <select id="getDayUserCount" resultType="com.dsh.account.vo.entity.DayData">
         select IFNULL(count(*),0) AS dayCount,DATE_FORMAT(insertTime,'%Y-%m-%d') AS `day` from t_app_user
         <where>
+            AND state != 3
             <if test="dto.startTime != null and dto.startTime != '' and dto.endTime != null and dto.endTime != ''">
                 AND insertTime between #{dto.startTime} and #{dto.endTime}
             </if>
@@ -255,6 +262,7 @@
     <select id="groupCityInfo" resultType="com.dsh.account.vo.GroupCityInfoVO">
         select IFNULL(count(*),0) AS userCount,cityCode,city from t_app_user
         <where>
+            AND state != 3
             <if test="dto.startTime != null and dto.startTime != '' and dto.endTime != null and dto.endTime != ''">
                 AND insertTime between #{dto.startTime} and #{dto.endTime}
             </if>
@@ -302,7 +310,7 @@
             <if test="query.salesmanUser!=null and query.salesmanUser!= ''">
                 and t2.salesmanUserId = #{query.salesmanUser}
             </if>
-            and t2.state != 3
         </where>
+        order by t2.insertTime desc, t2.id desc
     </select>
 </mapper>
diff --git a/cloud-server-account/src/main/resources/mapper/UserAuditMapper.xml b/cloud-server-account/src/main/resources/mapper/UserAuditMapper.xml
index 80bfe15..e29d87e 100644
--- a/cloud-server-account/src/main/resources/mapper/UserAuditMapper.xml
+++ b/cloud-server-account/src/main/resources/mapper/UserAuditMapper.xml
@@ -14,5 +14,6 @@
         <if test="query.state != null">
             and t1.state = #{query.state}
         </if>
+        order by t1.insertTime desc, t1.id desc
     </select>
 </mapper>
diff --git a/cloud-server-account/src/main/resources/mapper/UserIntegralChangesMapper.xml b/cloud-server-account/src/main/resources/mapper/UserIntegralChangesMapper.xml
index f83905f..d8bf479 100644
--- a/cloud-server-account/src/main/resources/mapper/UserIntegralChangesMapper.xml
+++ b/cloud-server-account/src/main/resources/mapper/UserIntegralChangesMapper.xml
@@ -22,5 +22,6 @@
         <if test="sTime !=null ">
             and t1.insertTime between #{sTime} and #{eTime}
         </if>
+        order by t1.insertTime desc, t1.id desc
     </select>
 </mapper>
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java
index b4aa058..760a91e 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java
@@ -7,6 +7,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.dsh.activity.entity.*;
+import com.dsh.activity.enums.HuiminCardPaymentTypeEnum;
 import com.dsh.activity.feignclient.account.AppUserClient;
 import com.dsh.activity.feignclient.account.CityClient;
 import com.dsh.activity.feignclient.account.StoreStaffClient;
@@ -834,15 +835,12 @@
                 return ResultUtil.tokenErr();
             }
             TPayHuimin tPayHuimin = payHuiminService.getById(id);
-            if (tPayHuimin.getPaymentType()==3){
-                // 后台录入直接退款
-                tPayHuimin.setStatus(3);
-                payHuiminService.updateById(tPayHuimin);
-                return ResultUtil.success();
-            }
             if (tPayHuimin == null) {
                 return ResultUtil.error("订单不存在");
             }
+            if (HuiminCardPaymentTypeEnum.isGift(tPayHuimin.getPaymentType())){
+                return ResultUtil.error("赠送惠民卡不允许退款");
+            }
             if (tPayHuimin.getStatus() == 3 && tPayHuimin.getRefundStatus() != 1) {
                 return ResultUtil.error("不可重复退款");
             }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
index 0f53331..4a0f1d5 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
@@ -124,13 +124,37 @@
 
     @RequestMapping("/base/pointMerchars/writeOff")
     public Object writeOff(@RequestBody WriteOffDTO dto) {
-        UserPointsMerchandise byId = userPointsMerchandiseService.getById(dto.getId());
-        byId.setStoreId(dto.getVerifiStoreId());
-        byId.setStatus(2);
-        byId.setVerificationTime(new Date());
-        byId.setUserId(null);
-        byId.setVerificationUserId(dto.getVerificationUserId());
-        return userPointsMerchandiseService.updateById(byId);
+        if (dto == null || dto.getId() == null) {
+            throw new IllegalArgumentException("门票记录不能为空");
+        }
+        if (!Integer.valueOf(1).equals(dto.getGoType()) && !Integer.valueOf(2).equals(dto.getGoType())) {
+            throw new IllegalArgumentException("入园方式参数不正确");
+        }
+
+        UserPointsMerchandise ticket = userPointsMerchandiseService.getById(dto.getId());
+        if (ticket == null) {
+            throw new IllegalArgumentException("门票记录不存在");
+        }
+        if (!Integer.valueOf(1).equals(ticket.getStatus())) {
+            throw new IllegalStateException("该门票已核销");
+        }
+
+        // 以待核销状态作为更新条件,避免并发请求重复核销同一张门票。
+        UserPointsMerchandise updatedTicket = new UserPointsMerchandise();
+        updatedTicket.setId(ticket.getId());
+        updatedTicket.setVerifiStoreId(dto.getVerifiStoreId());
+        updatedTicket.setStatus(2);
+        updatedTicket.setVerificationTime(new Date());
+        updatedTicket.setVerificationUserId(dto.getVerificationUserId());
+        updatedTicket.setGoType(dto.getGoType());
+        boolean updated = userPointsMerchandiseService.update(updatedTicket,
+                new LambdaQueryWrapper<UserPointsMerchandise>()
+                        .eq(UserPointsMerchandise::getId, ticket.getId())
+                        .eq(UserPointsMerchandise::getStatus, 1));
+        if (!updated) {
+            throw new IllegalStateException("该门票已核销");
+        }
+        return true;
     }
 
     @Autowired
@@ -1779,6 +1803,7 @@
                 map.put("id", pointsMerchandise.getId());
                 map.put("userId", pointsMerchandise.getUserId());
                 map.put("status", pointsMerchandise.getStatus());
+                map.put("goType", pointsMerchandise.getGoType());
                 map.put("payTime", sdf.format(pointsMerchandise.getPaymentTime()));
                 map.put("orderNumber", pointsMerchandise.getOrderNumber());
                 mapList.add(map);
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java
index 74e2f5d..6ebd9d1 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java
@@ -1,6 +1,5 @@
 package com.dsh.activity.controller;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.mb.cloud.common.data.controller.BaseController;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -8,18 +7,12 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.dsh.activity.entity.THuiminCard;
 import com.dsh.activity.entity.TPayHuimin;
-import com.dsh.activity.entity.TStudent;
-import com.dsh.activity.feignclient.account.StudentClient;
 import com.dsh.activity.service.HuiminCardService;
 import com.dsh.activity.service.PayHuiminService;
-import com.dsh.activity.util.UUIDUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
-import java.text.SimpleDateFormat;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -32,8 +25,6 @@
     private HuiminCardService tHuiminCardService;
     @Autowired
     private PayHuiminService payHuiminService;
-    @Autowired
-    private StudentClient studentClient;
 
 
     @PostMapping("/queryPage")
@@ -173,43 +164,6 @@
     }
     @GetMapping("/addPayHuiMing")
     public void addPayHuiMing(@RequestParam("studentId")Integer studentId, @RequestParam("cardId")Integer cardId){
-        TPayHuimin tPayHuimin = new TPayHuimin();
-
-        THuiminCard byId = tHuiminCardService.getById(cardId);
-        List<TStudent> studentByIds = studentClient.getStudentByIds(studentId + "");
-        if (CollUtil.isNotEmpty(studentByIds)){
-            tPayHuimin.setAppUserId(studentByIds.get(0).getAppUserId());
-        }
-        tPayHuimin.setSalesMoney(byId.getSalesMoney());
-        tPayHuimin.setStudentId(studentId+"");
-        switch (byId.getHuiMinType()) {
-            case 1:
-                // 年度卡
-                LocalDateTime localDateTime = LocalDateTime.now().plusDays(365);
-                // 将LocalDateTime转换为Date类型
-                Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
-                tPayHuimin.setEndTime(date);
-                break;
-            case 2:
-                // 年内卡
-                Date date1 = new Date();
-                date1.setMonth(11);
-                date1.setDate(31);
-                date1.setHours(23);
-                date1.setMinutes(59);
-                date1.setSeconds(57);
-                tPayHuimin.setEndTime(date1);
-                break;
-        }
-        tPayHuimin.setInsertTime(new Date());
-        tPayHuimin.setPaymentType(3);
-        tPayHuimin.setRefundStatus(1);
-        tPayHuimin.setCardId(byId.getId());
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
-        tPayHuimin.setCode(sdf.format(new Date()) + UUIDUtil.getNumberRandom(5));
-        System.err.println("支付数据" + tPayHuimin);
-        tPayHuimin.setPaymentTime(new Date());
-        tPayHuimin.setStatus(2);
-        payHuiminService.save(tPayHuimin);
+        tHuiminCardService.recordGiftHuiminCard(studentId, cardId);
     }
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java
index 3581e96..c5bdf33 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java
@@ -16,6 +16,8 @@
 import com.dsh.activity.feignclient.other.StoreClient;
 import com.dsh.activity.feignclient.other.model.Store;
 import com.dsh.activity.model.CouponListVo;
+import com.dsh.activity.model.CouponDeductionQuery;
+import com.dsh.activity.model.CouponDeductionVO;
 import com.dsh.activity.model.GrantCoupon;
 import com.dsh.activity.model.SendCouponReq;
 import com.dsh.activity.service.*;
@@ -75,6 +77,18 @@
 
     private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
 
+    /**
+     * 批量查询已核销优惠券的抵扣金额,供运营数据统计使用。
+     *
+     * @param query 用户优惠券领取记录 ID 集合
+     * @return 每条领取记录对应的抵扣金额
+     */
+    @ResponseBody
+    @PostMapping("/base/userCoupon/queryDeductionAmounts")
+    public List<CouponDeductionVO> queryDeductionAmounts(@RequestBody CouponDeductionQuery query) {
+        return userCouponService.queryDeductionAmounts(query);
+    }
+
     @PostMapping("/base/userConpon/getStuOfConpons")
     public List<CouponStuAvailableVo> queryUserWithConponList(@RequestParam("appUserId") Integer appUserId) {
 
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponPaymentController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponPaymentController.java
index 59f176a..9aff694 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponPaymentController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponPaymentController.java
@@ -7,6 +7,7 @@
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * @author zhibing.pu
@@ -54,4 +55,13 @@
         userCouponPayment.setUserId(null);
         userCouponPaymentService.updateById(userCouponPayment);
     }
+
+    /** 统计使用:仅返回现金购买成功的优惠券订单。 */
+    @ResponseBody
+    @PostMapping("/base/userCouponPayment/listPaid")
+    public List<UserCouponPayment> listPaid(){
+        return userCouponPaymentService.list(new QueryWrapper<UserCouponPayment>()
+                .eq("status", 2)
+                .eq("payType", 2));
+    }
 }
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
index 891715d..39ec97f 100644
--- 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
@@ -38,7 +38,10 @@
     //购买用户
     private List<Integer> appUserIds;
 
+    /** 赠送卡订单类型编码,仅供统计查询排除赠送金额。 */
+    private Integer giftPaymentType;
+
     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/TPayHuimin.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java
index b5febda..349c029 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java
@@ -80,7 +80,7 @@
     @TableField("status")
     private Integer status;
     /**
-     *付款方式1微信2支付宝 3后台录入
+     * 订单类型:1微信售卖、2支付宝售卖、3后台录入赠送
      */
     @TableField("paymentType")
     private Integer paymentType;
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserPointsMerchandise.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserPointsMerchandise.java
index 9c229b0..acbef2a 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserPointsMerchandise.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserPointsMerchandise.java
@@ -62,6 +62,11 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date verificationTime;
     /**
+     * 入园方式:1=手环,2=门票核销。仅在完成核销后有值。
+     */
+    @TableField("goType")
+    private Integer goType;
+    /**
      * 状态(1=待核销,2=已核销)
      */
     @TableField("status")
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/model/WriteOffDTO.java b/cloud-server-activity/src/main/java/com/dsh/activity/model/WriteOffDTO.java
index b553855..b7f9dc2 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/model/WriteOffDTO.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/model/WriteOffDTO.java
@@ -17,4 +17,9 @@
 
     // 核销门店id 如果状态为已核销 verifiStoreId为null 则是平台核销
     private Integer verifiStoreId;
+
+    /**
+     * 入园方式:1=手环,2=门票核销。
+     */
+    private Integer goType;
 }
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
index b404b22..b7592b6 100644
--- 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
@@ -14,6 +14,7 @@
     private String huiMinName;          // 玩湃惠民卡名称
     private Integer huiMinType;          // 玩湃惠民卡类型(1:年度卡,2:年内卡)
     private BigDecimal salesMoney;      // 售卖金额(精确计算)
+    private Integer paymentType;        // 订单类型(1:微信售卖,2:支付宝售卖,3:赠送)
 
     // 关联信息
     private Integer operatorId;
@@ -30,6 +31,10 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date paymentTime;  // 购买时间[1,8](@ref)
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date refundTime;
+    private Integer refundStatus;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date endTime;      // 有效期
 
@@ -39,4 +44,4 @@
     private Integer useTimes;           // 已用次数
     private Integer status;             // 状态(1:使用中,2:已退款)
     private String orderNumber;             // 支付流水号
-}
\ No newline at end of file
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/HuiminCardService.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/HuiminCardService.java
index 59c3dd1..17672d9 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/HuiminCardService.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/HuiminCardService.java
@@ -25,4 +25,12 @@
     List<THuiminCard> getHuiminAgreementAndListNolimit(Integer storeId);
 
     List<MyHuiminCardVO> getMyHuiminCardList(Integer pageNo, Integer pageSize, Integer appUserId);
+
+    /**
+     * 为指定绑定人员录入赠送的玩湃惠民卡订单。
+     *
+     * @param studentId 绑定人员ID,不可为空
+     * @param cardId    玩湃惠民卡ID,不可为空
+     */
+    void recordGiftHuiminCard(Integer studentId, Integer cardId);
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/UserCouponService.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/UserCouponService.java
index b9cfdd3..22d4c68 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/UserCouponService.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/UserCouponService.java
@@ -3,6 +3,8 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.dsh.activity.entity.UserCoupon;
 import com.dsh.activity.model.CouponListVo;
+import com.dsh.activity.model.CouponDeductionQuery;
+import com.dsh.activity.model.CouponDeductionVO;
 import com.dsh.activity.model.request.CouponPackageReq;
 import com.dsh.activity.model.response.CouponPackageResp;
 
@@ -41,4 +43,12 @@
 
 
     List<CouponPackageResp> queryCouponPackagesList(Integer uid, CouponPackageReq req);
+
+    /**
+     * 批量查询已核销用户优惠券的抵扣金额。
+     *
+     * @param query 用户优惠券领取记录 ID 集合
+     * @return 每条领取记录对应的抵扣金额
+     */
+    List<CouponDeductionVO> queryDeductionAmounts(CouponDeductionQuery query);
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/HuiminCardServiceImpl.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/HuiminCardServiceImpl.java
index 82f4200..ad750f5 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/HuiminCardServiceImpl.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/HuiminCardServiceImpl.java
@@ -1,20 +1,28 @@
 package com.dsh.activity.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.dsh.activity.entity.BenefitsVideoClassification;
 import com.dsh.activity.entity.THuiminCard;
-import com.dsh.activity.mapper.BenefitsVideoClassificationMapper;
+import com.dsh.activity.entity.TPayHuimin;
+import com.dsh.activity.entity.TStudent;
+import com.dsh.activity.enums.HuiminCardPaymentStatusEnum;
+import com.dsh.activity.enums.HuiminCardPaymentTypeEnum;
+import com.dsh.activity.enums.HuiminCardRefundStatusEnum;
+import com.dsh.activity.enums.HuiminCardTypeEnum;
+import com.dsh.activity.feignclient.account.StudentClient;
 import com.dsh.activity.mapper.HuiminCardMapper;
-import com.dsh.activity.model.BenefitsVedioChangeStateVO;
-import com.dsh.activity.model.QueryBenefitsVedioVO;
-import com.dsh.activity.model.TQueryBenefitsVO;
-import com.dsh.activity.model.response.HuiminCardVO;
 import com.dsh.activity.model.response.MyHuiminCardVO;
 import com.dsh.activity.service.HuiminCardService;
-import com.dsh.activity.service.IBenefitsVideoClassificationService;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.dsh.activity.service.PayHuiminService;
+import com.dsh.activity.util.UUIDUtil;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -23,6 +31,18 @@
  */
 @Service
 public class HuiminCardServiceImpl extends ServiceImpl<HuiminCardMapper, THuiminCard> implements HuiminCardService {
+
+    private static final int ANNUAL_CARD_VALID_DAYS = 365;
+    private static final int YEAR_END_MONTH = Calendar.DECEMBER;
+    private static final int YEAR_END_DAY = 31;
+    private static final int DAY_END_HOUR = 23;
+    private static final int DAY_END_MINUTE = 59;
+    private static final int DAY_END_SECOND = 59;
+
+    @Resource
+    private PayHuiminService payHuiminService;
+    @Resource
+    private StudentClient studentClient;
 
     @Override
     public List<THuiminCard> getHuiminAgreementAndList(Integer pageNo, Integer pageSize, Integer storeId) {
@@ -37,4 +57,75 @@
     public List<MyHuiminCardVO> getMyHuiminCardList(Integer pageNo, Integer pageSize,Integer appUserId) {
         return this.baseMapper.getMyHuiminCardList(pageNo,pageSize,appUserId);
     }
+
+    /**
+     * 为指定绑定人员录入赠送的玩湃惠民卡订单。
+     * 业务流程:参数校验 → 校验卡及人员 → 计算有效期 → 保存赠送订单。
+     *
+     * @param studentId 绑定人员ID,不可为空
+     * @param cardId    玩湃惠民卡ID,不可为空
+     * @throws IllegalArgumentException 惠民卡或绑定人员不存在时抛出
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void recordGiftHuiminCard(Integer studentId, Integer cardId) {
+        // STEP 1: 校验录入所需的基础参数。
+        if (studentId == null || cardId == null) {
+            throw new IllegalArgumentException("绑定人员和惠民卡不能为空");
+        }
+
+        // STEP 2: 查询并校验惠民卡和绑定人员,确保订单关联数据有效。
+        THuiminCard huiminCard = this.getById(cardId);
+        if (huiminCard == null) {
+            throw new IllegalArgumentException("玩湃惠民卡不存在");
+        }
+        List<TStudent> students = studentClient.getStudentByIds(String.valueOf(studentId));
+        if (CollUtil.isEmpty(students) || students.get(0).getAppUserId() == null) {
+            throw new IllegalArgumentException("绑定人员不存在或未关联用户");
+        }
+
+        // STEP 3: 按卡类型计算赠送卡的有效期。
+        Date currentTime = new Date();
+        TPayHuimin giftOrder = new TPayHuimin();
+        giftOrder.setSalesMoney(huiminCard.getSalesMoney());
+        giftOrder.setAppUserId(students.get(0).getAppUserId());
+        giftOrder.setStudentId(String.valueOf(studentId));
+        giftOrder.setEndTime(calculateEndTime(huiminCard.getHuiMinType(), currentTime));
+
+        // STEP 4: 以赠送类型保存已支付订单,保留卡面金额但不参与售卖金额统计。
+        giftOrder.setInsertTime(currentTime);
+        giftOrder.setPaymentTime(currentTime);
+        giftOrder.setPaymentType(HuiminCardPaymentTypeEnum.GIFT.getCode());
+        giftOrder.setStatus(HuiminCardPaymentStatusEnum.PAID.getCode());
+        giftOrder.setRefundStatus(HuiminCardRefundStatusEnum.PENDING_REFUND.getCode());
+        giftOrder.setCardId(huiminCard.getId());
+        giftOrder.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(5));
+        payHuiminService.save(giftOrder);
+    }
+
+    /**
+     * 根据惠民卡类型计算有效期。
+     *
+     * @param cardType    惠民卡类型
+     * @param currentTime 当前时间
+     * @return 有效期结束时间;未知类型时返回 null
+     */
+    private Date calculateEndTime(Integer cardType, Date currentTime) {
+        if (HuiminCardTypeEnum.ANNUAL_CARD.matches(cardType)) {
+            LocalDateTime expirationTime = LocalDateTime.now().plusDays(ANNUAL_CARD_VALID_DAYS);
+            return Date.from(expirationTime.atZone(ZoneId.systemDefault()).toInstant());
+        }
+        if (HuiminCardTypeEnum.CURRENT_YEAR_CARD.matches(cardType)) {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(currentTime);
+            calendar.set(Calendar.MONTH, YEAR_END_MONTH);
+            calendar.set(Calendar.DAY_OF_MONTH, YEAR_END_DAY);
+            calendar.set(Calendar.HOUR_OF_DAY, DAY_END_HOUR);
+            calendar.set(Calendar.MINUTE, DAY_END_MINUTE);
+            calendar.set(Calendar.SECOND, DAY_END_SECOND);
+            calendar.set(Calendar.MILLISECOND, 0);
+            return calendar.getTime();
+        }
+        return null;
+    }
 }
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 d3e15ac..ffea8ad 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
@@ -9,6 +9,7 @@
 import com.dsh.activity.entity.THuiminRecord;
 import com.dsh.activity.entity.TPayHuimin;
 import com.dsh.activity.entity.TStudent;
+import com.dsh.activity.enums.HuiminCardPaymentTypeEnum;
 import com.dsh.activity.feignclient.account.AppUserClient;
 import com.dsh.activity.feignclient.account.StudentClient;
 import com.dsh.activity.feignclient.account.model.AppUser;
@@ -97,6 +98,7 @@
 
     @Override
     public Map<String, BigDecimal> getStaticsData(HuiminPayQuery query) {
+        query.setGiftPaymentType(HuiminCardPaymentTypeEnum.GIFT.getCode());
         return baseMapper.getStaticsData(query);
     }
 
@@ -104,14 +106,9 @@
     public ResultUtil<?> refund(Integer id) throws AlipayApiException {
         TPayHuimin payHuimin = this.getById(id);
         if (Objects.nonNull(payHuimin)) {
-            // 后台录入订单直接修改为已退款
-            if (payHuimin.getPaymentType()==3){
-                payHuimin.setStatus(3);
-                payHuimin.setRefundStatus(3);
-                payHuimin.setRefundNumber(payHuimin.getCode());
-                payHuimin.setRefundTime(new Date());
-                this.updateById(payHuimin);
-                return ResultUtil.success();
+            // 赠送订单不产生支付金额,禁止退款。
+            if (HuiminCardPaymentTypeEnum.isGift(payHuimin.getPaymentType())){
+                throw new IllegalArgumentException("赠送惠民卡不允许退款");
             }
             Integer count = huiminRecordService.lambdaQuery()
                     .eq(THuiminRecord::getPayId, payHuimin.getId())
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/UserCouponServiceImpl.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/UserCouponServiceImpl.java
index 83a7f6f..6bb6d60 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/UserCouponServiceImpl.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/UserCouponServiceImpl.java
@@ -16,6 +16,8 @@
 import com.dsh.activity.feignclient.other.model.StoreDetailOfCourse;
 import com.dsh.activity.mapper.*;
 import com.dsh.activity.model.ConponJsonRuleModel;
+import com.dsh.activity.model.CouponDeductionQuery;
+import com.dsh.activity.model.CouponDeductionVO;
 import com.dsh.activity.model.CouponListVo;
 import com.dsh.activity.model.request.CouponPackageReq;
 import com.dsh.activity.model.response.CouponPackageResp;
@@ -24,12 +26,18 @@
 import com.dsh.activity.util.GDMapGeocodingUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.annotation.Resource;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -42,6 +50,8 @@
  */
 @Service
 public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCoupon> implements UserCouponService {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserCouponServiceImpl.class);
 
     @Resource
     private CoursePackageClient coursePackageClient;
@@ -72,6 +82,60 @@
     @Resource
     private SiteClient siteClient;
 
+    /**
+     * 批量解析已核销优惠券的固定抵扣金额,避免统计页面逐条远程查询优惠券。
+     *
+     * @param query 用户优惠券领取记录 ID 集合
+     * @return 每条领取记录对应的抵扣金额;无固定抵扣规则时返回 0
+     */
+    @Override
+    public List<CouponDeductionVO> queryDeductionAmounts(CouponDeductionQuery query) {
+        if (query == null || query.getUserCouponIds() == null || query.getUserCouponIds().isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        Set<Long> userCouponIds = new LinkedHashSet<>(query.getUserCouponIds());
+        List<UserCoupon> userCoupons = this.list(new QueryWrapper<UserCoupon>()
+                .in("id", userCouponIds));
+        if (userCoupons.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        Set<Integer> couponIds = userCoupons.stream()
+                .map(UserCoupon::getCouponId)
+                .filter(java.util.Objects::nonNull)
+                .collect(Collectors.toSet());
+        List<Coupon> coupons = couponIds.isEmpty()
+                ? Collections.emptyList()
+                : couponMapper.selectBatchIds(couponIds);
+        Map<Integer, Coupon> couponMap = coupons.stream()
+                .collect(Collectors.toMap(Coupon::getId, coupon -> coupon));
+
+        List<CouponDeductionVO> result = new ArrayList<>();
+        for (UserCoupon userCoupon : userCoupons) {
+            CouponDeductionVO deduction = new CouponDeductionVO();
+            deduction.setUserCouponId(userCoupon.getId());
+            deduction.setDeductionAmount(getCouponDeductionAmount(couponMap.get(userCoupon.getCouponId())));
+            result.add(deduction);
+        }
+        return result;
+    }
+
+    /** 解析优惠券规则中的固定抵扣金额。 */
+    private BigDecimal getCouponDeductionAmount(Coupon coupon) {
+        if (coupon == null || coupon.getContent() == null) {
+            return BigDecimal.ZERO;
+        }
+        try {
+            JSONObject content = JSON.parseObject(coupon.getContent());
+            BigDecimal deductionAmount = content.getBigDecimal("deductionAmount");
+            return deductionAmount == null ? BigDecimal.ZERO : deductionAmount.max(BigDecimal.ZERO);
+        } catch (Exception e) {
+            LOGGER.warn("解析优惠券抵扣规则失败,couponId={}", coupon.getId(), e);
+            return BigDecimal.ZERO;
+        }
+    }
+
 
     /**
      * 获取购买课程可用优惠券列表
diff --git a/cloud-server-activity/src/main/resources/mapper/BodySideAppointmentsMapper.xml b/cloud-server-activity/src/main/resources/mapper/BodySideAppointmentsMapper.xml
index 1bd1b43..95f9a05 100644
--- a/cloud-server-activity/src/main/resources/mapper/BodySideAppointmentsMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/BodySideAppointmentsMapper.xml
@@ -44,6 +44,7 @@
                 </foreach>
             </if>
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
 
-</mapper>
\ No newline at end of file
+</mapper>
diff --git a/cloud-server-activity/src/main/resources/mapper/IntroduceRewardsMapper.xml b/cloud-server-activity/src/main/resources/mapper/IntroduceRewardsMapper.xml
index 510e09a..1a2dfc2 100644
--- a/cloud-server-activity/src/main/resources/mapper/IntroduceRewardsMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/IntroduceRewardsMapper.xml
@@ -46,5 +46,6 @@
                 </when>
             </choose>
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
 </mapper>
diff --git a/cloud-server-activity/src/main/resources/mapper/IntroduceUserMapper.xml b/cloud-server-activity/src/main/resources/mapper/IntroduceUserMapper.xml
index 8061e86..1825772 100644
--- a/cloud-server-activity/src/main/resources/mapper/IntroduceUserMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/IntroduceUserMapper.xml
@@ -21,5 +21,6 @@
                 and t1.introduceRewards = #{query.introduceId}
             </if>
         </where>
+        order by t1.registerTime desc, t1.id desc
     </select>
 </mapper>
diff --git a/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml b/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml
index 52aaa37..57e1c7c 100644
--- a/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/PayHuiminMapper.xml
@@ -9,10 +9,13 @@
         thc.huiMinName,
         thc.huiMinType,
         tph.salesMoney,
+        tph.paymentType,
         thc.operatorId,
         thc.storeIds,
         tph.appUserId,
         tph.paymentTime,
+        tph.refundTime,
+        tph.refundStatus,
         tph.endTime,
         tph.studentId,
         thc.id as carId,
@@ -72,14 +75,17 @@
         LEFT JOIN t_huimin_card thc ON tph.cardId = thc.id
         <where>
             tph.id IS NOT NULL
+            <if test="query.giftPaymentType != null">
+                AND (tph.paymentType IS NULL OR tph.paymentType != #{query.giftPaymentType})
+            </if>
             <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 test="query.operatorId !=null">
+                AND thc.operatorId = #{query.operatorId}
             </if>
             <if test="query.useId !=null and query.useId != ''">
                 AND FIND_IN_SET(#{query.useId},thc.useIds)
@@ -122,10 +128,13 @@
         thc.huiMinName,
         thc.huiMinType,
         tph.salesMoney,
+        tph.paymentType,
         thc.operatorId,
         thc.storeIds,
         tph.appUserId,
         tph.paymentTime,
+        tph.refundTime,
+        tph.refundStatus,
         tph.endTime,
         tph.studentId,
         tph.status,
@@ -138,14 +147,18 @@
         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.giftPaymentType != null">
+                AND (tph.paymentType IS NULL OR tph.paymentType != #{query.giftPaymentType})
+            </if>
             <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 test="query.operatorId !=null">
+                AND thc.operatorId = #{query.operatorId}
             </if>
             <if test="query.useId !=null and query.useId != ''">
                 AND FIND_IN_SET(#{query.useId},thc.useIds)
diff --git a/cloud-server-activity/src/main/resources/mapper/UserCouponMapper.xml b/cloud-server-activity/src/main/resources/mapper/UserCouponMapper.xml
index cb2df28..606e839 100644
--- a/cloud-server-activity/src/main/resources/mapper/UserCouponMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/UserCouponMapper.xml
@@ -17,5 +17,6 @@
               (
             b.useScope = 1 or (b.useScope = 2 and b.id IN (SELECT couponId FROM t_coupon_city  where provinceCode = #{provinceCode} and cityCode = #{cityCode}) )
                            or (b.useScope = 3 and b.id in (select couponId from t_coupon_store where storeId = #{storeId})))
+        order by a.insertTime desc, a.id desc
     </select>
 </mapper>
diff --git a/cloud-server-activity/src/main/resources/mapper/UserPointsMerchandiseMapper.xml b/cloud-server-activity/src/main/resources/mapper/UserPointsMerchandiseMapper.xml
index 4b38443..5f832fb 100644
--- a/cloud-server-activity/src/main/resources/mapper/UserPointsMerchandiseMapper.xml
+++ b/cloud-server-activity/src/main/resources/mapper/UserPointsMerchandiseMapper.xml
@@ -18,9 +18,10 @@
 
 
     <select id="getAmount" resultType="com.dsh.activity.model.PointMerchandiseIncomeVo">
-        select t1.insertTime,t2.cash  from t_user_points_merchandise t1
+        select COALESCE(t1.paymentTime, t1.insertTime) as insertTime, t1.cash from t_user_points_merchandise t1
         left join t_points_merchandise t2 on t1.pointsMerchandiseId = t2.id
-        where t1.payStatus =2
+        where t1.payStatus = 2
+        and (t1.state is null or t1.state = 1)
         <if test="storeIds.size()>0">
             and t1.storeId IN
             <foreach collection="storeIds" separator="," item="storeId" open="(" close=")">
diff --git a/cloud-server-auth/src/main/java/cn/mb/cloud/auth/controller/UserController.java b/cloud-server-auth/src/main/java/cn/mb/cloud/auth/controller/UserController.java
index 31a2c41..c5f62a8 100644
--- a/cloud-server-auth/src/main/java/cn/mb/cloud/auth/controller/UserController.java
+++ b/cloud-server-auth/src/main/java/cn/mb/cloud/auth/controller/UserController.java
@@ -1,11 +1,18 @@
 package cn.mb.cloud.auth.controller;
 
 import cn.mb.cloud.auth.service.IUserDetailsService;
+import cn.mb.cloud.auth.feignclient.AccountAuditClient;
 import cn.mb.cloud.auth.warpper.GetTokenRequest;
 import cn.mb.cloud.auth.warpper.RefreshTokenRequest;
 import cn.mb.cloud.auth.warpper.TokenResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/oauth")
@@ -14,6 +21,9 @@
     @Autowired
     private IUserDetailsService userDetailsService;
 
+    @Resource
+    private AccountAuditClient accountAuditClient;
+
 
     /**
      * 获取认证token
@@ -21,15 +31,54 @@
      */
     @ResponseBody
     @PostMapping("/getToken")
-    public TokenResponse getToken(@RequestBody GetTokenRequest request){
+    public TokenResponse getToken(@RequestBody GetTokenRequest request, HttpServletRequest httpRequest){
+        TokenResponse response = null;
+        String error = null;
         try {
-            return userDetailsService.getToken(request);
+            response = userDetailsService.getToken(request);
+            return response;
         }catch (Exception e){
             e.printStackTrace();
+            error = e.getMessage();
+        } finally {
+            appendLoginAudit(request, httpRequest, response != null && response.getToken() != null, error);
         }
         return null;
     }
 
+    private void appendLoginAudit(GetTokenRequest request, HttpServletRequest httpRequest, boolean success, String error) {
+        try {
+            Map<String, Object> audit = new HashMap<String, Object>();
+            audit.put("sourceService", "mb-cloud-auth");
+            audit.put("sourceType", "LOGIN");
+            audit.put("operationType", "LOGIN");
+            audit.put("riskLevel", "NORMAL");
+            audit.put("operationName", "账号登录");
+            audit.put("requestMethod", "POST");
+            audit.put("requestUri", "/oauth/getToken");
+            audit.put("requestParams", "username=" + mask(request == null ? null : request.getUsername()));
+            audit.put("userAccount", mask(request == null ? null : request.getUsername()));
+            audit.put("result", success ? "SUCCESS" : "FAIL");
+            audit.put("errorMessage", error == null ? null : error.replaceAll("(?i)(password|token)\\s*[:=]\\s*[^,\\s&}]+", "$1=***"));
+            audit.put("clientIp", clientIp(httpRequest));
+            audit.put("createdAt", new Date());
+            accountAuditClient.append(audit);
+        } catch (Exception ignored) {
+            // 审计链路不可用时绝不能影响认证主流程;客户端会输出 Feign 异常用于告警。
+        }
+    }
+
+    private String mask(String value) {
+        if (value == null || value.length() <= 4) return "***";
+        return value.substring(0, 3) + "***" + value.substring(value.length() - 2);
+    }
+
+    private String clientIp(HttpServletRequest request) {
+        if (request == null) return null;
+        String forwarded = request.getHeader("X-Forwarded-For");
+        return forwarded == null || forwarded.trim().isEmpty() ? request.getRemoteAddr() : forwarded.split(",")[0].trim();
+    }
+
     /**
      * 刷新token
      * @param request
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java
index 694add2..266c167 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java
@@ -3,6 +3,7 @@
 
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.poi.excel.ExcelUtil;
+import cn.mb.cloud.common.core.exception.BusinessException;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -139,20 +140,6 @@
             List<Integer> operatorId = cttService.list(new QueryWrapper<Competition>()
                     .eq("operatorId", operatorId1)).stream().map(Competition::getId).collect(Collectors.toList());
             query.setUserIds(operatorId);
-        } else if (query.getStoreId() != null) {
-            List<Competition> list = cttService.list(new QueryWrapper<Competition>());
-            List<Integer> integers = new ArrayList<>();
-            for (Competition competition : list) {
-                for (String s : competition.getStoreId().split(",")) {
-                    if (s.equals(""+query.getStoreId())){
-                        integers.add(competition.getId());
-                    }
-                }
-            }
-            if (integers.isEmpty()){
-                integers.add(-1);
-            }
-            query.setUserIds(integers);
         }
         List<PaymentCompetition> paymentCompetitions = paymentCompetitionService.listAll(query);
         List<PaymentCompetition> result = new ArrayList<>();
@@ -171,17 +158,7 @@
             }
             return result;
         } else if (query.getStoreId() != null) {
-            for (PaymentCompetition paymentCompetition : paymentCompetitions) {
-                Integer competitionId = paymentCompetition.getCompetitionId();
-                Competition byId = cttService.getById(competitionId);
-                if (byId != null) {
-                    String storeId = byId.getStoreId();
-                    if (storeId.contains(query.getStoreId().toString())) {
-                        result.add(paymentCompetition);
-                    }
-                }
-            }
-            return result;
+            return paymentCompetitions;
         }
         return paymentCompetitions;
     }
@@ -769,7 +746,8 @@
                 wrapper.ne(Competition::getAuditStatus,2);
             }
             wrapper.in(Competition::getStoreId,listQuery.getIds());
-            wrapper.orderByDesc(Competition::getInsertTime);
+            wrapper.orderByDesc(Competition::getInsertTime)
+                    .orderByDesc(Competition::getId);
             Page<Competition> page = cttService.page(competitionPage, wrapper);
             for (Competition record : page.getRecords()) {
                 // 查询当前赛事有多少人报名了
@@ -812,7 +790,8 @@
             integers.add(1);
             integers.add(3);
             wrapper.in(Competition::getAuditStatus, integers);
-            wrapper.orderByDesc(Competition::getInsertTime);
+            wrapper.orderByDesc(Competition::getInsertTime)
+                    .orderByDesc(Competition::getId);
 
             Page<Competition> page = cttService.page(competitionPage, wrapper);
             return page;
@@ -861,41 +840,14 @@
         }
     }
 
+    /**
+     * 更新活动配置。
+     *
+     * @param competition 管理端提交的活动信息
+     */
     @PostMapping("/base/competition/update")
-    public void update(@RequestBody Competition competition) {
-        try {
-            if (competition.getStartTime().after(new Date())) {
-                competition.setStatus(1);
-            }
-            if (competition.getStartTime().before(new Date())) {
-                if (competition.getEndTime().after(new Date())) {
-                    competition.setStatus(2);
-                } else {
-                    competition.setStatus(3);
-                }
-
-                if(competition.getStatus() == 2){
-                    //添加勋章数据
-                    List<PaymentCompetition> list = paymentCompetitionService.list(new QueryWrapper<PaymentCompetition>()
-                            .eq("competitionId", competition.getId()).eq("payStatus", 2).eq("state", 1));
-                    Set<Integer> collect = list.stream().map(PaymentCompetition::getAppUserId).collect(Collectors.toSet());
-                    for (Integer integer : collect) {
-                        int count = paymentCompetitionService.count(new QueryWrapper<PaymentCompetition>()
-                                .eq("appUserId", integer).eq("payStatus", 2).eq("state", 1));
-                        StudentHonor studentHonor = new StudentHonor();
-                        studentHonor.setAppUserId(integer);
-                        studentHonor.setHonorType(2);
-                        studentHonor.setNumber(count);
-                        studentHonorClient.saveStudentHonor(studentHonor);
-                    }
-                }
-            }
-            cttService.updateById(competition);
-
-
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+    public void update(@RequestBody Competition competition) throws BusinessException {
+        cttService.updateCompetition(competition);
     }
 
     @Resource
@@ -1234,4 +1186,3 @@
         return list1.stream().map(PaymentCompetition::getAppUserId).collect(Collectors.toList());
     }
 }
-
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java b/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java
index 8498834..d69be32 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java
@@ -33,6 +33,11 @@
     @TableField("competitionId")
     private Integer competitionId;
     /**
+     * 下单时活动举办门店 ID 列表快照。
+     */
+    @TableField("competitionStoreIds")
+    private String competitionStoreIds;
+    /**
      * 用户id
      */
     @TableField("appUserId")
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionQuery.java b/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionQuery.java
index 33b5ce6..024ea25 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionQuery.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionQuery.java
@@ -19,4 +19,6 @@
     private Integer insertType;
     private Integer operatorId;
     private Integer storeId;
+    /** 是否包含已退款支付记录 */
+    private Boolean includeRefund;
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java
index 3bffc46..3c6c773 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java
@@ -2,6 +2,7 @@
 
 import com.alipay.api.AlipayApiException;
 import com.baomidou.mybatisplus.extension.service.IService;
+import cn.mb.cloud.common.core.exception.BusinessException;
 import com.dsh.competition.entity.Competition;
 import com.dsh.competition.model.CompetitionInfo;
 import com.dsh.competition.model.CompetitionListVo;
@@ -20,6 +21,14 @@
  */
 public interface CompetitionService extends IService<Competition> {
 
+    /**
+     * 修改活动并校验已报名数据的完整性。
+     *
+     * @param competition 管理端提交的活动信息
+     * @throws cn.mb.cloud.common.core.exception.BusinessException 活动不存在或编辑数据不合法时抛出
+     */
+    void updateCompetition(Competition competition) throws BusinessException;
+
 
     /**
      * 获取赛事列表
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
index ce57566..a5280aa 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
@@ -15,9 +15,11 @@
 import com.alipay.api.response.AlipayTradeOrderSettleResponse;
 import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.alipay.api.response.AlipayTradeRoyaltyRelationBindResponse;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dsh.competition.entity.*;
+import com.dsh.competition.enums.CompetitionStatusEnum;
 import com.dsh.competition.feignclient.account.AppUserClient;
 import com.dsh.competition.feignclient.account.StudentClient;
 import com.dsh.competition.feignclient.account.model.AppUser;
@@ -36,9 +38,11 @@
 import com.dsh.competition.service.UserCompetitionService;
 import com.dsh.competition.util.*;
 import com.dsh.competition.util.wx.WxV3PayConfig;
+import cn.mb.cloud.common.core.exception.BusinessException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
@@ -85,6 +89,104 @@
 
     @Autowired
     private CompetitionService cttService;
+
+    /**
+     * 修改活动,并确保修改不会破坏既有报名记录。
+     *
+     * @param competition 管理端提交的活动信息
+     * @throws BusinessException 活动不存在、时间范围非法或人数容量不足时抛出
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateCompetition(Competition competition) throws BusinessException {
+        validateUpdateRequest(competition);
+
+        // STEP 1: 读取原活动,避免前端传入部分字段时覆盖既有数据。
+        Competition originalCompetition = getById(competition.getId());
+        if (originalCompetition == null) {
+            throw new BusinessException("活动不存在或已删除");
+        }
+
+        // STEP 2: 校验人数容量,保证已报名记录始终处于有效的活动容量内。
+        validateApplicantsNumber(competition);
+
+        // STEP 3: 仅更新活动配置;支付订单金额为快照,价格调整不会修改既有订单。
+        competition.setStatus(resolveCompetitionStatus(originalCompetition, competition));
+        updateById(competition);
+    }
+
+    /**
+     * 校验编辑请求中必填字段和基础数值范围。
+     *
+     * @param competition 待校验的活动信息
+     */
+    private void validateUpdateRequest(Competition competition) throws BusinessException {
+        if (competition == null || competition.getId() == null) {
+            throw new BusinessException("活动编号不能为空");
+        }
+        if (competition.getStartTime() == null || competition.getEndTime() == null
+                || competition.getRegisterEndTime() == null) {
+            throw new BusinessException("活动时间和截止报名时间不能为空");
+        }
+        if (competition.getApplicantsNumber() == null || competition.getApplicantsNumber() < 0) {
+            throw new BusinessException("报名人数必须为非负整数");
+        }
+        if (competition.getBaseNumber() != null && competition.getBaseNumber() < 0) {
+            throw new BusinessException("基础报名人数必须为非负整数");
+        }
+        if (competition.getStartAge() != null && competition.getEndAge() != null
+                && competition.getStartAge() > competition.getEndAge()) {
+            throw new BusinessException("报名最小年龄不能大于最大年龄");
+        }
+        validatePrices(competition);
+    }
+
+    /**
+     * 校验各支付价格不可为负数。
+     *
+     * @param competition 待校验的活动信息
+     */
+    private void validatePrices(Competition competition) throws BusinessException {
+        if ((competition.getCashPrice() != null && competition.getCashPrice() < 0)
+                || (competition.getPlayPaiCoin() != null && competition.getPlayPaiCoin() < 0)
+                || (competition.getClassPrice() != null && competition.getClassPrice() < 0)) {
+            throw new BusinessException("支付价格不能小于零");
+        }
+    }
+
+    /**
+     * 校验调整后的容量不会小于当前已报名人数。
+     *
+     * @param competition 待校验的活动信息
+     */
+    private void validateApplicantsNumber(Competition competition) throws BusinessException {
+        int registeredCount = userCompetitionService.count(new LambdaQueryWrapper<UserCompetition>()
+                .eq(UserCompetition::getCompetitionId, competition.getId()));
+        if (competition.getApplicantsNumber() < registeredCount) {
+            throw new BusinessException("报名人数不能小于已报名人数" + registeredCount);
+        }
+    }
+
+    /**
+     * 根据当前时间刷新活动状态,并保持已取消活动的取消状态。
+     *
+     * @param originalCompetition 数据库中的原活动
+     * @param competition 待保存的活动信息
+     * @return 计算后的活动状态编码
+     */
+    private Integer resolveCompetitionStatus(Competition originalCompetition, Competition competition) {
+        if (CompetitionStatusEnum.CANCELED.getCode().equals(originalCompetition.getStatus())) {
+            return CompetitionStatusEnum.CANCELED.getCode();
+        }
+        Date currentTime = new Date();
+        if (currentTime.before(competition.getStartTime())) {
+            return CompetitionStatusEnum.NOT_STARTED.getCode();
+        }
+        if (currentTime.before(competition.getEndTime())) {
+            return CompetitionStatusEnum.IN_PROGRESS.getCode();
+        }
+        return CompetitionStatusEnum.ENDED.getCode();
+    }
 
 
     private String aliAppid = "2021004105665036";//支付宝appid
@@ -278,6 +380,7 @@
         String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5);
         paymentCompetition.setCode(code);
         paymentCompetition.setCompetitionId(paymentCompetitionVo.getId());
+        paymentCompetition.setCompetitionStoreIds(competition.getStoreId());
         paymentCompetition.setAppUserId(uid);
         paymentCompetition.setPayType(paymentCompetitionVo.getPayType());
         paymentCompetition.setAmount(money.doubleValue());
diff --git a/cloud-server-competition/src/main/resources/mapper/ParticipantMapper.xml b/cloud-server-competition/src/main/resources/mapper/ParticipantMapper.xml
index 2ea92f7..d39aa75 100644
--- a/cloud-server-competition/src/main/resources/mapper/ParticipantMapper.xml
+++ b/cloud-server-competition/src/main/resources/mapper/ParticipantMapper.xml
@@ -12,6 +12,7 @@
         <if test="state !=null and state !='' and state ==3">
             and t3.payStatus =3
         </if>
+        order by t1.insertTime desc, t1.id desc
     </select>
 
     <select id="getPeopleFromId1" resultType="com.dsh.competition.entity.UserCompetition">
@@ -23,7 +24,7 @@
         <if test="null != state and state == 3">
             and payStatus = 3
         </if>
-        ) order by insertTime desc limit #{offset}, #{limit}
+        ) order by insertTime desc, id desc limit #{offset}, #{limit}
     </select>
 
     <select id="getPeopleFromIdCount" resultType="java.lang.Integer">
@@ -52,4 +53,4 @@
         </if>
     </select>
 
-</mapper>
\ No newline at end of file
+</mapper>
diff --git a/cloud-server-competition/src/main/resources/mapper/PaymentCompetitionMapper.xml b/cloud-server-competition/src/main/resources/mapper/PaymentCompetitionMapper.xml
index 3292740..1a92d22 100644
--- a/cloud-server-competition/src/main/resources/mapper/PaymentCompetitionMapper.xml
+++ b/cloud-server-competition/src/main/resources/mapper/PaymentCompetitionMapper.xml
@@ -32,7 +32,7 @@
         <if test="null != type and 4 == type">
             and a.payStatus = 3
         </if>
-        order by a.insertTime desc limit #{pageNo}, #{pageSize}
+        order by a.insertTime desc, a.id desc limit #{pageNo}, #{pageSize}
     </select>
     <select id="queryDatas" resultType="com.dsh.competition.feignclient.model.BillingRequest">
         SELECT
@@ -74,11 +74,22 @@
                     #{id}
                 </foreach>
             </if>
+            <if test="query.storeId != null">
+                AND FIND_IN_SET(#{query.storeId}, t1.competitionStoreIds)
+            </if>
             <if test="sTime !=null and sTime!= '' and eTime !=null and eTime!= ''">
                 and t1.insertTime between #{sTime} and #{eTime}
             </if>
-        and t1.payStatus = 2
+        <choose>
+            <when test="query.includeRefund != null and query.includeRefund">
+                and t1.payStatus IN (2, 3)
+            </when>
+            <otherwise>
+                and t1.payStatus = 2
+            </otherwise>
+        </choose>
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
     <select id="queryBycode" resultType="java.lang.Integer">
         SELECT cp.storeId
@@ -90,4 +101,4 @@
         select  count(1)
         from t_user_competition where competitionId = #{id}
     </select>
-</mapper>
\ No newline at end of file
+</mapper>
diff --git a/cloud-server-course/src/main/java/com/dsh/course/model/RegisterOrderVO.java b/cloud-server-course/src/main/java/com/dsh/course/model/RegisterOrderVO.java
index 3de0fba..bbcd27e 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/model/RegisterOrderVO.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/model/RegisterOrderVO.java
@@ -45,6 +45,8 @@
     private Date insertTime;
     // 支付金额
     private BigDecimal money;
+    /** 用户优惠券领取记录ID */
+    private Long userCouponId;
     // 玩湃币价格/积分
     private Integer playPaiCoin;
     // 该字段用于展示在前端
diff --git a/cloud-server-course/src/main/resources/mapper/CancelledClassesMapper.xml b/cloud-server-course/src/main/resources/mapper/CancelledClassesMapper.xml
index 4126cec..726b07d 100644
--- a/cloud-server-course/src/main/resources/mapper/CancelledClassesMapper.xml
+++ b/cloud-server-course/src/main/resources/mapper/CancelledClassesMapper.xml
@@ -34,6 +34,7 @@
                 </foreach>
             </if>
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
     <select id="getRefund" resultType="com.dsh.course.entity.MoneyBack">
         select * from t_back_money where status = 1
diff --git a/cloud-server-course/src/main/resources/mapper/TCoursePackageDiscountMapper.xml b/cloud-server-course/src/main/resources/mapper/TCoursePackageDiscountMapper.xml
index 2f6ddce..e1cad76 100644
--- a/cloud-server-course/src/main/resources/mapper/TCoursePackageDiscountMapper.xml
+++ b/cloud-server-course/src/main/resources/mapper/TCoursePackageDiscountMapper.xml
@@ -36,6 +36,7 @@
             and t1.type =#{type}
         </if>
         group by t1.coursePackageId
+        order by max(t1.insertTime) desc, max(t1.id) desc
     </select>
 
 
@@ -60,5 +61,6 @@
             and t1.type =#{type}
         </if>
         group by t1.coursePackageId
+        order by max(t1.insertTime) desc, max(t1.id) desc
     </select>
 </mapper>
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/PermissionsFilter.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/PermissionsFilter.java
index 3811282..be480e3 100644
--- a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/PermissionsFilter.java
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/PermissionsFilter.java
@@ -227,6 +227,10 @@
 
     public PermissionResult hasPermission(ServerWebExchange exchange, ServerHttpRequest request) {
         String uri = request.getURI().getRawPath();
+        // 审计写入接口仅供服务通过注册中心直连,不能经公网网关伪造审计记录。
+        if (uri.startsWith("/internal/audit-logs")) {
+            return PermissionResult.FORBIDDEN;
+        }
         if(uri.contains("v2/api-docs")){
             return PermissionResult.PASS;
         }
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/AppUserClient.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/AppUserClient.java
index 729f091..f6ab987 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/AppUserClient.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/AppUserClient.java
@@ -28,6 +28,10 @@
 @FeignClient("mb-cloud-account")
 public interface AppUserClient {
 
+    /** Only invoked by the super-administrator sensitive data query. */
+    @PostMapping("/internal/sensitive/app-user/{id}")
+    Map<String, Object> sensitiveAppUser(@PathVariable("id") Integer id);
+
     /**
      * 根据介绍有礼id查询当前活动参与次数
      */
@@ -77,6 +81,7 @@
      */
     @RequestMapping("/base/appUser/addAppUser1")
     Object addAppUser1(@RequestBody TAppUser query);
+
     /**
      * 获取用户学员列表
      * @param appUserId
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/model/VipPayment.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/model/VipPayment.java
index b67b395..dac2c95 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/model/VipPayment.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/account/model/VipPayment.java
@@ -69,6 +69,8 @@
     @TableField("insertTime")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
     private Date insertTime;
+    @TableField("refundTime")
+    private Date refundTime;
 
 
     public static String CODE(){
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/CouponClient.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/CouponClient.java
index dae5b1d..fa1f21b 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/CouponClient.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/CouponClient.java
@@ -20,6 +20,19 @@
 @FeignClient(value = "mb-cloud-activity")
 public interface CouponClient {
 
+    /**
+     * 批量查询已核销优惠券的抵扣金额。
+     *
+     * @param query 用户优惠券领取记录 ID 集合
+     * @return 每条优惠券领取记录对应的抵扣金额
+     */
+    @PostMapping("/base/userCoupon/queryDeductionAmounts")
+    List<CouponDeductionVO> queryDeductionAmounts(@RequestBody CouponDeductionQuery query);
+
+    /** 所有已支付的积分+现金优惠券购买订单(平台营收统计使用)。 */
+    @PostMapping("/base/userCouponPayment/listPaid")
+    List<UserCouponPayment> listPaidCouponPayments();
+
 
     @PostMapping("/base/coupon/queryCouponListSearch")
     List<Map<String,Object>> getCouponListOfSearch(@RequestBody CouponListOfSearch ofSearch);
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
index 1a36b0a..fd16649 100644
--- 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
@@ -39,7 +39,10 @@
     //购买用户
     private List<Integer> appUserIds;
 
+    /** 赠送卡订单类型编码,仅供统计查询排除赠送金额。 */
+    private Integer giftPaymentType;
+
     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/TPayHuimin.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TPayHuimin.java
index 005826b..0ed42b7 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TPayHuimin.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TPayHuimin.java
@@ -80,7 +80,7 @@
     @TableField("status")
     private Integer status;
     /**
-     *付款方式1微信2支付宝
+     *订单类型:1微信售卖、2支付宝售卖、3后台录入赠送
      */
     @TableField("paymentType")
     private Integer paymentType;
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/WriteOffDTO.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/WriteOffDTO.java
index b3ea0e8..3be0842 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/WriteOffDTO.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/WriteOffDTO.java
@@ -15,4 +15,9 @@
 
     // 核销门店id 如果状态为已核销 verifiStoreId为null 则是平台核销
     private Integer verifiStoreId;
+
+    /**
+     * 入园方式:1=手环,2=门票核销。
+     */
+    private Integer goType;
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/CompetitionQuery.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/CompetitionQuery.java
index 85639c8..073d675 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/CompetitionQuery.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/CompetitionQuery.java
@@ -22,4 +22,6 @@
     private Integer insertType;
     private Integer operatorId;
     private Integer storeId;
+    /** 是否包含已退款支付记录 */
+    private Boolean includeRefund;
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/PaymentCompetition.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/PaymentCompetition.java
index dae64a7..1508cec 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/PaymentCompetition.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/competition/model/PaymentCompetition.java
@@ -32,6 +32,11 @@
     @TableField("competitionId")
     private Integer competitionId;
     /**
+     * 下单时活动举办门店 ID 列表快照。
+     */
+    @TableField("competitionStoreIds")
+    private String competitionStoreIds;
+    /**
      * 用户id
      */
     @TableField("appUserId")
diff --git a/cloud-server-management/src/main/java/com/dsh/course/mapper/UserMapper.java b/cloud-server-management/src/main/java/com/dsh/course/mapper/UserMapper.java
index 9383906..32b8778 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/mapper/UserMapper.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/mapper/UserMapper.java
@@ -66,4 +66,10 @@
 
     List<UserListVO> searchUsers(@Param("query") UserQuery userQuery);
 
-}
\ No newline at end of file
+    void deleteStoreRelations(@Param("userId") Integer userId);
+
+    void insertStoreRelations(@Param("userId") Integer userId, @Param("storeIds") List<Integer> storeIds);
+
+    List<Integer> getStoreIdsByUserId(@Param("userId") Integer userId);
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/DataStatisticsController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/DataStatisticsController.java
index 990dbda..52c271e 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/DataStatisticsController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/DataStatisticsController.java
@@ -7,6 +7,12 @@
 import com.dsh.course.feignClient.account.*;
 import com.dsh.course.feignClient.account.model.*;
 import com.dsh.course.feignClient.activity.PointMercharsClient;
+import com.dsh.course.feignClient.activity.CouponClient;
+import com.dsh.course.feignClient.activity.PayHuiminClient;
+import com.dsh.course.feignClient.activity.model.CouponDeductionQuery;
+import com.dsh.course.feignClient.activity.model.CouponDeductionVO;
+import com.dsh.course.feignClient.activity.model.HuiminPayQuery;
+import com.dsh.course.feignClient.activity.model.UserCouponPayment;
 import com.dsh.course.feignClient.competition.CompetitionClient;
 import com.dsh.course.feignClient.competition.model.CompetionVO;
 import com.dsh.course.feignClient.competition.model.Competition;
@@ -43,6 +49,7 @@
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
@@ -72,6 +79,33 @@
             return storeId;
         }
         return null;
+    }
+
+    /**
+     * 计算门店每日营业整小时数。相同的起止时间表示全天营业,结束时间早于
+     * 开始时间时按跨午夜营业处理。
+     */
+    private long getDailyBusinessHours(String startTime, String endTime) {
+        if (ToolUtil.isEmpty(startTime) || ToolUtil.isEmpty(endTime)) {
+            return 0;
+        }
+
+        try {
+            LocalTime start = LocalTime.parse(startTime);
+            LocalTime end = LocalTime.parse(endTime);
+            long minutes = Duration.between(start, end).toMinutes();
+            if (minutes <= 0) {
+                minutes += Duration.ofDays(1).toMinutes();
+            }
+            return Duration.ofMinutes(minutes).toHours();
+        } catch (DateTimeException e) {
+            return 0;
+        }
+    }
+
+    private long getStoreOperatingHours(TStore store, Date now) {
+        long operatingDays = Math.max(0, DateUtil.betweenDay(store.getCreateTime(), now, true));
+        return operatingDays * getDailyBusinessHours(store.getStartTime(), store.getEndTime());
     }
 
     @Autowired
@@ -106,6 +140,10 @@
     private SiteClient siteClient;
     @Resource
     private PointMercharsClient pointMercharsClient;
+    @Resource
+    private CouponClient couponClient;
+    @Resource
+    private PayHuiminClient payHuiminClient;
     @Resource
     private RefundCoursePackageClient refundCoursePackageClient;
     @Resource
@@ -155,10 +193,13 @@
         RechargeRecordsQuery rechargeRecordsQuery = new RechargeRecordsQuery();
         // 赛事活动查询query
         CompetitionQuery competitionQuery = new CompetitionQuery();
+        competitionQuery.setIncludeRefund(true);
         // 会员支付查询query
         IncomeQuery incomeQuery = new IncomeQuery();
+        incomeQuery.setIncludeRefund(true);
         // 场地预约记录查询query
         SiteBookingQuery siteBookingQuery = new SiteBookingQuery();
+        siteBookingQuery.setIncludeRefund(true);
         // 智慧球场查询query
         GameDataQuery gameDataQuery = new GameDataQuery();
         // 筛选运营商的是时候使用
@@ -193,9 +234,21 @@
                  incomeQuery.setInsertType(roleType);
         rechargeRecordsQuery.setObjectId(UserExt.getUser().getObjectId());
         List<IncomeVO> incomeVOS = new ArrayList<>();
+        Set<Long> usedCouponIds = new HashSet<>();
         // 会员支付记录
         List<VipPayment> vipPayments = vipPaymentClient.registrationList(incomeQuery);
         for (VipPayment vipPayment : vipPayments) {
+            if (vipPayment.getPayStatus() == 3 && vipPayment.getAmount() != null) {
+                IncomeVO payment = new IncomeVO();
+                payment.setInsertTime(vipPayment.getPayTime() == null ? vipPayment.getInsertTime() : vipPayment.getPayTime());
+                payment.setAmount(BigDecimal.valueOf(vipPayment.getAmount()));
+                incomeVOS.add(payment);
+                IncomeVO refund = new IncomeVO();
+                refund.setInsertTime(vipPayment.getRefundTime() == null ? vipPayment.getInsertTime() : vipPayment.getRefundTime());
+                refund.setRefundAmount(BigDecimal.valueOf(vipPayment.getAmount()));
+                incomeVOS.add(refund);
+                continue;
+            }
             IncomeVO temp = new IncomeVO();
             if (vipPayment.getState()!=3){
                 temp.setInsertTime(vipPayment.getPayTime());
@@ -229,6 +282,10 @@
                 temp.setAmount(registerOrderVO.getMoney());
             }
             if (registerOrderVO.getPayStatus()==2){
+                if (registerOrderVO.getUserCouponId() != null) {
+                    usedCouponIds.add(registerOrderVO.getUserCouponId());
+                    temp.setId(registerOrderVO.getUserCouponId().toString());
+                }
                 incomeVOS.add(temp);
             }
         }
@@ -239,13 +296,28 @@
         // 报名活动
         List<PaymentCompetition> competitions = competitionClient.listAllPayment(competitionQuery);
         for (PaymentCompetition competition : competitions) {
-            if (competition.getPayStatus() != 2) {
-                continue;
-            }
             if (competition.getPayType()==3 || competition.getPayType()==4){
                 continue;
             }
-            if (competition.getState()==3)continue;
+            if (competition.getState()==3) {
+                continue;
+            }
+            if (competition.getPayStatus() == 3 && competition.getAmount() != null) {
+                IncomeVO payment = new IncomeVO();
+                payment.setInsertTime(competition.getPayTime() == null
+                        ? competition.getInsertTime() : competition.getPayTime());
+                payment.setAmount(BigDecimal.valueOf(competition.getAmount()));
+                incomeVOS.add(payment);
+                IncomeVO refund = new IncomeVO();
+                refund.setInsertTime(competition.getRefundTime() == null
+                        ? competition.getInsertTime() : competition.getRefundTime());
+                refund.setRefundAmount(BigDecimal.valueOf(competition.getAmount()));
+                incomeVOS.add(refund);
+                continue;
+            }
+            if (competition.getPayStatus() != 2) {
+                continue;
+            }
             IncomeVO temp = new IncomeVO();
             temp.setInsertTime(competition.getPayTime());
             if (competition.getAmount() != null) {
@@ -260,7 +332,22 @@
             List<SiteBooking> siteBookings = siteClient.listAll(siteBookingQuery);
             for (SiteBooking siteBooking : siteBookings) {
                 IncomeVO temp = new IncomeVO();
-                if(siteBooking.getStatus()==0 || siteBooking.getStatus()==5){
+                if (siteBooking.getStatus() == 5) {
+                    if (siteBooking.getPayMoney() != null) {
+                        IncomeVO payment = new IncomeVO();
+                        payment.setInsertTime(siteBooking.getPayTime() == null
+                                ? siteBooking.getInsertTime() : siteBooking.getPayTime());
+                        payment.setAmount(BigDecimal.valueOf(siteBooking.getPayMoney()));
+                        incomeVOS.add(payment);
+                        IncomeVO refund = new IncomeVO();
+                        refund.setInsertTime(siteBooking.getCancelTime() == null
+                                ? siteBooking.getInsertTime() : siteBooking.getCancelTime());
+                        refund.setRefundAmount(BigDecimal.valueOf(siteBooking.getPayMoney()));
+                        incomeVOS.add(refund);
+                    }
+                    continue;
+                }
+                if (siteBooking.getStatus() == 0) {
                     continue;
                 }
                 if (siteBooking.getPayType() ==3 || siteBooking.getPayType() ==4)continue;
@@ -268,7 +355,22 @@
                 if (siteBooking.getPayMoney() != null) {
                     temp.setAmount(new BigDecimal(siteBooking.getPayMoney().toString()));
                 }
+                if (siteBooking.getUserCouponId() != null) {
+                    usedCouponIds.add(siteBooking.getUserCouponId());
+                    temp.setId(siteBooking.getUserCouponId().toString());
+                }
                 incomeVOS.add(temp);
+            }
+        }
+
+        Map<Long, BigDecimal> couponDeductionAmounts = getCouponDeductionAmounts(usedCouponIds);
+        applyCouponDeductions(incomeVOS, couponDeductionAmounts);
+
+        // 惠民卡和优惠券购买不归属到单一课程/场地门店,当前仅在平台或运营商汇总中计入。
+        if (storeId == null) {
+            appendHuiminIncome(incomeVOS, operatorId);
+            if (operatorId == null) {
+                appendCouponPurchaseIncome(incomeVOS);
             }
         }
 
@@ -316,176 +418,198 @@
                 incomeVOS.add(temp);
             }
         }
-        // 最终返回的数据
-        Map<String, List<Object>> monthlyData = new HashMap<>();
-        // 创建一个 Map 用于存储每年的累计 amount
-        Map<Integer, BigDecimal> yearToTotalAmountMap = new HashMap<>();
-        // 初始化一个 BigDecimal 用于累加
-        BigDecimal totalAmount1 = BigDecimal.ZERO;
-        // 用于返回图表上的总营收 年度营收 月度 周度 日度
-        List<Object> objects = new ArrayList<>();
-        // 遍历 incomeVOS
-        for (IncomeVO incomeVO1 : incomeVOS) {
-            // 总营收
-            BigDecimal total = incomeVO1.getAmount();
-            // 累加到总金额
-            totalAmount1 = totalAmount1.add(total);
-
-            Date insertTime = incomeVO1.getInsertTime();
-            BigDecimal amount1 = incomeVO1.getAmount();
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTime(insertTime);
-            int year = calendar.get(Calendar.YEAR); // 获取年份
-            // 更新年份对应的累计 amount
-            if (yearToTotalAmountMap.containsKey(year)) {
-                BigDecimal totalAmount = yearToTotalAmountMap.get(year);
-                yearToTotalAmountMap.put(year, totalAmount.add(amount1));
-            } else {
-                yearToTotalAmountMap.put(year, amount1);
-            }
-        }
-        objects.add(totalAmount1);
-        // 创建一个新的列表,按年份升序排列
-        List<Integer> sortedYears = new ArrayList<>(yearToTotalAmountMap.keySet());
-        Collections.sort(sortedYears);
-        // 创建一个新的 IncomeVO 列表,包含按年份累计的 amount
-        List<Object> resultIncomeVOS = new ArrayList<>();
-        // 当前年往前推十年
-        List<Integer> integers1 = new ArrayList<>();
-        int years = DateUtil.year(new Date());
-        for (int i = 0; i < 10; i++) {
-            integers1.add(years-i);
-         }
-        List<Object> collect = integers1.stream().sorted().collect(Collectors.toList());
-        List<Object> objects1 = new ArrayList<>();
-        for (Object o : collect) {
-            BigDecimal orDefault = yearToTotalAmountMap.getOrDefault(Integer.valueOf(o.toString()), BigDecimal.ZERO);
-            objects1.add(orDefault);
-        }
-        monthlyData.put("yearIncome",objects1);
-        BigDecimal yearIn = new BigDecimal("0.00");
-        for (Object o : objects1) {
-            yearIn = yearIn.add(new BigDecimal(o.toString()));
-        }
-        BigDecimal orDefault = yearToTotalAmountMap.getOrDefault(years, BigDecimal.ZERO);
-        objects.add(orDefault);
-        // 创建一个 Map 用于存储今年每个月的累计 amount
-        Map<Integer, BigDecimal> monthToTotalAmountMap = new HashMap<>();
-        Calendar calendar = Calendar.getInstance();
-        int currentYear = calendar.get(Calendar.YEAR);
-        List<BigDecimal> monthlyAmountList = new ArrayList<>(Collections.nCopies(12, BigDecimal.ZERO));
-
-        for (IncomeVO incomeVO1 : incomeVOS) {
-            Calendar calendar1 = Calendar.getInstance();
-            calendar1.setTime(incomeVO1.getInsertTime());
-            int year = calendar1.get(Calendar.YEAR);
-            int month = calendar1.get(Calendar.MONTH) + 1; // 月份从0开始,所以需要加1
-            if (year == currentYear) {
-                BigDecimal totalAmount = monthlyAmountList.get(month - 1);
-                totalAmount = totalAmount.add(incomeVO1.getAmount());
-                monthlyAmountList.set(month - 1, totalAmount);
-            }
-        }
-        monthlyData.put("monthIncome", Collections.singletonList(monthlyAmountList));
-        //yearMount
-        BigDecimal monthI = new BigDecimal("0.00");
-        for (BigDecimal bigDecimal : monthlyAmountList) {
-            monthI = monthI.add(bigDecimal);
-        }
-        objects.add(monthI);
-        // 获取当前月份
-        LocalDate currentDate = LocalDate.now();
-        int currentMonth = currentDate.getMonthValue();
-        // 初始化一个长度为当前月份的天数的列表,并将每一天的金额初始化为零
-        int daysInCurrentMonth = currentDate.lengthOfMonth();
-        List<BigDecimal> weekAmount = new ArrayList<>();
-
-        // 获取最近四周
-        LocalDateTime minNow = LocalDateTime.now().with(LocalTime.MIN);
-        LocalDateTime maxNow = LocalDateTime.now().with(LocalTime.MAX);
-        // 周度数据
-        LocalDateTime week1Start = minNow.minusDays(6);
-        LocalDateTime week1End   = maxNow;
-
-        LocalDateTime week2Start = minNow.minusDays(13);
-        LocalDateTime week2End = minNow.minusDays(7);
-
-        LocalDateTime week3Start = minNow.minusDays(20);
-        LocalDateTime week3End = minNow.minusDays(14);
-
-        LocalDateTime week4Start = minNow.minusDays(27);
-        LocalDateTime week4End = minNow.minusDays(21);
-
-        // 计算每个周的amount总和
-        BigDecimal tAmount1 = BigDecimal.ZERO;
-        BigDecimal tAmount2 = BigDecimal.ZERO;
-        BigDecimal tAmount3 = BigDecimal.ZERO;
-        BigDecimal tAmount4 = BigDecimal.ZERO;
-        for (IncomeVO incomeVO1 : incomeVOS) {
-            Date insertTime = incomeVO1.getInsertTime();
-            // 将Date转换为LocalDateTime
-            Instant instant = insertTime.toInstant();
-            ZoneId zoneId = ZoneId.systemDefault();
-            LocalDateTime dateTime = instant.atZone(zoneId).toLocalDateTime();
-            // 判断该数据属于哪个周
-            if (dateTime.isAfter(week1Start) && dateTime.isBefore(week1End)) {
-                BigDecimal amount1 = incomeVO1.getAmount();
-                tAmount1=tAmount1.add(amount1);
-            } else if (dateTime.isAfter(week2Start) && dateTime.isBefore(week2End)) {
-                BigDecimal amount1 = incomeVO1.getAmount();
-                tAmount2=tAmount2.add(amount1);
-            } else if (dateTime.isAfter(week3Start) && dateTime.isBefore(week3End)) {
-                BigDecimal amount1 = incomeVO1.getAmount();
-                tAmount4=tAmount3.add(amount1);
-            } else if (dateTime.isAfter(week4Start) && dateTime.isBefore(week4End)) {
-                BigDecimal amount1 = incomeVO1.getAmount();
-                tAmount4=tAmount4.add(amount1);
-            }
-        }
-        weekAmount.add(tAmount1);
-        weekAmount.add(tAmount2);
-        weekAmount.add(tAmount3);
-        weekAmount.add(tAmount4);
-        monthlyData.put("weekIncome", Collections.singletonList(weekAmount));
-        BigDecimal weekIn = new BigDecimal("0.00");
-        for (BigDecimal bigDecimal : weekAmount) {
-            weekIn = weekIn.add(bigDecimal);
-        }
-        objects.add(weekIn);
-        LocalDateTime currentDateTime = LocalDateTime.now();
-        List<BigDecimal> amountByDay = new ArrayList<>(Collections.nCopies(7, BigDecimal.ZERO));
-        for (IncomeVO incomeVO3 : incomeVOS) {
-            Date insertTime = incomeVO3.getInsertTime();
-            // 将 Date 转换为 LocalDateTime
-            LocalDateTime insertDateTime = LocalDateTime.ofInstant(insertTime.toInstant(), ZoneId.systemDefault());
-            // 计算日期与当前日期的差距
-            long daysDifference = ChronoUnit.DAYS.between(insertDateTime.toLocalDate(), currentDateTime.toLocalDate());
-            // 如果日期在七天内,累加金额
-            if (daysDifference >= 0 && daysDifference < 7) {
-                int index = (int) (6 - daysDifference); // 计算对应的索引位置
-                BigDecimal amount3 = incomeVO3.getAmount();
-                BigDecimal updatedAmount = amountByDay.get(index).add(amount3);
-                amountByDay.set(index, updatedAmount);
-
-            }
-        }
-        monthlyData.put("dayIncome", Collections.singletonList(amountByDay));
-        BigDecimal totalToday = new BigDecimal("0.00");
-        for (BigDecimal bigDecimal : amountByDay) {
-            totalToday = totalToday.add(bigDecimal);
-        }
-        objects.add(totalToday);
-        // 最后put
-        monthlyData.put("yearMount",objects);
-
-        ArrayList<Object> integers = new ArrayList<>();
-        int year = DateUtil.year(new Date());
-        for (int i = 0; i < 10; i++) {
-            integers.add(year-i);
-        }
-        List<Object> collect1 = integers.stream().sorted().collect(Collectors.toList());
-        monthlyData.put("year",collect1);
+        Map<String, Object> monthlyData = buildIncomeStatistics(incomeVOS);
         return monthlyData;
+    }
+
+    /** 惠民卡采用支付、退款两条事实流水,赠送卡不计营收。 */
+    private void appendHuiminIncome(List<IncomeVO> incomeRecords, Integer operatorId) {
+        HuiminPayQuery query = new HuiminPayQuery();
+        query.setGiftPaymentType(3);
+        if (operatorId != null) {
+            query.setOperatorId(operatorId.longValue());
+        }
+        List<SalesDetailVO> records = payHuiminClient.exportData(query);
+        if (records == null) {
+            return;
+        }
+        for (SalesDetailVO record : records) {
+            if (record == null || record.getSalesMoney() == null || record.getPaymentTime() == null) {
+                continue;
+            }
+            IncomeVO payment = new IncomeVO();
+            payment.setInsertTime(record.getPaymentTime());
+            payment.setAmount(record.getSalesMoney());
+            incomeRecords.add(payment);
+            if (Integer.valueOf(3).equals(record.getStatus())
+                    || Integer.valueOf(2).equals(record.getRefundStatus())
+                    || Integer.valueOf(3).equals(record.getRefundStatus())) {
+                IncomeVO refund = new IncomeVO();
+                refund.setInsertTime(record.getRefundTime() == null ? record.getPaymentTime() : record.getRefundTime());
+                refund.setRefundAmount(record.getSalesMoney());
+                incomeRecords.add(refund);
+            }
+        }
+    }
+
+    /** 仅计入积分+现金的成功优惠券购买,纯积分兑换不形成现金营收。 */
+    private void appendCouponPurchaseIncome(List<IncomeVO> incomeRecords) {
+        List<UserCouponPayment> records = couponClient.listPaidCouponPayments();
+        if (records == null) {
+            return;
+        }
+        for (UserCouponPayment record : records) {
+            if (record == null || record.getCash() == null || record.getPaymentTime() == null) {
+                continue;
+            }
+            IncomeVO payment = new IncomeVO();
+            payment.setInsertTime(record.getPaymentTime());
+            payment.setAmount(BigDecimal.valueOf(record.getCash()));
+            incomeRecords.add(payment);
+        }
+    }
+
+    /** 构建总计及年、月、周、日四个粒度的四维收入统计结果。 */
+    private Map<String, Object> buildIncomeStatistics(List<IncomeVO> incomeRecords) {
+        Map<String, Object> result = new HashMap<>();
+        LocalDate today = LocalDate.now();
+        int currentYear = today.getYear();
+        List<IncomeStatisticsVO> yearly = new ArrayList<>();
+        List<Object> years = new ArrayList<>();
+        for (int year = currentYear - 9; year <= currentYear; year++) {
+            final int statisticYear = year;
+            yearly.add(sumIncomeStatistics(incomeRecords, record -> getRecordDate(record)
+                    .getYear() == statisticYear));
+            years.add(year);
+        }
+
+        List<IncomeStatisticsVO> monthly = new ArrayList<>();
+        for (int month = 1; month <= 12; month++) {
+            final int statisticMonth = month;
+            monthly.add(sumIncomeStatistics(incomeRecords, record -> {
+                LocalDate date = getRecordDate(record);
+                return date.getYear() == currentYear && date.getMonthValue() == statisticMonth;
+            }));
+        }
+
+        List<IncomeStatisticsVO> weekly = new ArrayList<>();
+        for (int weekIndex = 3; weekIndex >= 0; weekIndex--) {
+            LocalDate startDate = today.minusDays(weekIndex * 7L + 6L);
+            LocalDate endDate = today.minusDays(weekIndex * 7L);
+            weekly.add(sumIncomeStatistics(incomeRecords, record -> {
+                LocalDate date = getRecordDate(record);
+                return !date.isBefore(startDate) && !date.isAfter(endDate);
+            }));
+        }
+
+        List<IncomeStatisticsVO> daily = new ArrayList<>();
+        for (int dayIndex = 6; dayIndex >= 0; dayIndex--) {
+            LocalDate statisticDate = today.minusDays(dayIndex);
+            daily.add(sumIncomeStatistics(incomeRecords, record -> getRecordDate(record)
+                    .equals(statisticDate)));
+        }
+
+        IncomeStatisticsVO total = sumIncomeStatistics(incomeRecords, record -> true);
+        IncomeStatisticsVO currentYearStatistics = yearly.get(yearly.size() - 1);
+        IncomeStatisticsVO currentMonthStatistics = monthly.get(today.getMonthValue() - 1);
+        IncomeStatisticsVO currentWeekStatistics = sumIncomeStatistics(incomeRecords, record -> {
+            LocalDate date = getRecordDate(record);
+            return !date.isBefore(today.minusDays(6)) && !date.isAfter(today);
+        });
+        IncomeStatisticsVO currentDayStatistics = daily.get(daily.size() - 1);
+
+        result.put("incomeStatistics", total);
+        result.put("netIncomeAmount", total.getNetIncomeAmount());
+        result.put("couponDeductionAmount", total.getCouponDeductionAmount());
+        result.put("refundAmount", total.getRefundAmount());
+        result.put("yearIncomeStatistics", yearly);
+        result.put("monthIncomeStatistics", monthly);
+        result.put("weekIncomeStatistics", weekly);
+        result.put("dayIncomeStatistics", daily);
+        result.put("year", years);
+        // 兼容既有图表消费字段,值调整为总营收金额。
+        result.put("yearIncome", yearly.stream().map(IncomeStatisticsVO::getTotalIncomeAmount)
+                .collect(Collectors.toList()));
+        result.put("monthIncome", Collections.singletonList(monthly.stream()
+                .map(IncomeStatisticsVO::getTotalIncomeAmount).collect(Collectors.toList())));
+        result.put("weekIncome", Collections.singletonList(weekly.stream()
+                .map(IncomeStatisticsVO::getTotalIncomeAmount).collect(Collectors.toList())));
+        result.put("dayIncome", Collections.singletonList(daily.stream()
+                .map(IncomeStatisticsVO::getTotalIncomeAmount).collect(Collectors.toList())));
+        result.put("yearMount", Arrays.asList(total.getTotalIncomeAmount(),
+                currentYearStatistics.getTotalIncomeAmount(), currentMonthStatistics.getTotalIncomeAmount(),
+                currentWeekStatistics.getTotalIncomeAmount(), currentDayStatistics.getTotalIncomeAmount()));
+        return result;
+    }
+
+    /** 按给定时间条件汇总四个收入维度。 */
+    private IncomeStatisticsVO sumIncomeStatistics(List<IncomeVO> incomeRecords,
+                                                     Predicate<IncomeVO> timePredicate) {
+        IncomeStatisticsVO statistics = new IncomeStatisticsVO();
+        for (IncomeVO record : incomeRecords) {
+            if (record.getInsertTime() == null || !timePredicate.test(record)) {
+                continue;
+            }
+            BigDecimal receivedAmount = getZeroIfNull(record.getAmount());
+            BigDecimal couponAmount = getZeroIfNull(record.getCouponDeductionAmount());
+            BigDecimal refundAmount = getZeroIfNull(record.getRefundAmount());
+            statistics.setTotalIncomeAmount(statistics.getTotalIncomeAmount()
+                    .add(receivedAmount).add(couponAmount));
+            statistics.setCouponDeductionAmount(statistics.getCouponDeductionAmount().add(couponAmount));
+            statistics.setRefundAmount(statistics.getRefundAmount().add(refundAmount));
+        }
+        statistics.setNetIncomeAmount(statistics.getTotalIncomeAmount()
+                .subtract(statistics.getCouponDeductionAmount())
+                .subtract(statistics.getRefundAmount()));
+        return statistics;
+    }
+
+    /** 将收入记录时间转换为本地日期。 */
+    private LocalDate getRecordDate(IncomeVO record) {
+        return LocalDateTime.ofInstant(record.getInsertTime().toInstant(), ZoneId.systemDefault()).toLocalDate();
+    }
+
+    /** 空金额按零参与统计。 */
+    private BigDecimal getZeroIfNull(BigDecimal amount) {
+        return amount == null ? BigDecimal.ZERO : amount;
+    }
+
+    /** 将批量查询到的优惠券抵扣金额回填到对应收入记录。 */
+    private void applyCouponDeductions(List<IncomeVO> incomeRecords,
+                                       Map<Long, BigDecimal> couponDeductionAmounts) {
+        for (IncomeVO record : incomeRecords) {
+            if (record.getId() == null) {
+                continue;
+            }
+            try {
+                record.setCouponDeductionAmount(couponDeductionAmounts.getOrDefault(
+                        Long.valueOf(record.getId()), BigDecimal.ZERO));
+            } catch (NumberFormatException ignored) {
+                record.setCouponDeductionAmount(BigDecimal.ZERO);
+            }
+        }
+    }
+
+    /**
+     * 批量获取已使用优惠券的抵扣金额,避免按订单逐条调用优惠券服务。
+     *
+     * @param usedCouponIds 用户优惠券领取记录 ID 集合
+     * @return 用户优惠券领取记录 ID 与抵扣金额的映射(单位:元)
+     */
+    private Map<Long, BigDecimal> getCouponDeductionAmounts(Set<Long> usedCouponIds) {
+        if (usedCouponIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        CouponDeductionQuery query = new CouponDeductionQuery();
+        query.setUserCouponIds(new ArrayList<>(usedCouponIds));
+        List<CouponDeductionVO> deductions = couponClient.queryDeductionAmounts(query);
+        if (deductions == null || deductions.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        return deductions.stream()
+                .filter(deduction -> deduction.getUserCouponId() != null)
+                .collect(Collectors.toMap(CouponDeductionVO::getUserCouponId,
+                        deduction -> getZeroIfNull(deduction.getDeductionAmount()), BigDecimal::add));
     }
 
     /**
@@ -1034,20 +1158,7 @@
         List<TStore> list = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getOperatorId, 0));
         long l1=0;
         for (TStore tStore : list) {
-            long l = DateUtil.betweenDay(tStore.getCreateTime(), new Date(), true);
-            String startTime = tStore.getStartTime();
-            String endTime = tStore.getEndTime();
-            String s = startTime.split(":")[0];
-            String s1 = endTime.split(":")[1];
-            Integer integer = Integer.valueOf(s);
-            Integer integer1 = Integer.valueOf(s1);
-            Integer a =0;
-            if(integer==0 && integer1==0){
-                a=24;
-            }else {
-                a= integer1-integer;
-            }
-            l1 += l * a;
+            l1 += getStoreOperatingHours(tStore, new Date());
         }
         map.put("allHour",l1);
         return map;
@@ -1079,20 +1190,7 @@
         List<TStore> lists = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getOperatorId, id));
         long l1=0;
         for (TStore tStore : lists) {
-            long l = DateUtil.betweenDay(tStore.getCreateTime(), new Date(), true);
-            String startTime = tStore.getStartTime();
-            String endTime = tStore.getEndTime();
-            String s = startTime.split(":")[0];
-            String s1 = endTime.split(":")[1];
-            Integer integer = Integer.valueOf(s);
-            Integer integer1 = Integer.valueOf(s1);
-            Integer a =0;
-            if(integer==0 && integer1==0){
-                a=24;
-            }else {
-                a= integer-integer1;
-            }
-            l1 += l * a;
+            l1 += getStoreOperatingHours(tStore, new Date());
         }
         map.put("allHour",l1);
         return map;
@@ -1117,20 +1215,7 @@
         List<TStore> lists = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getOperatorId, 0));
         long l1=0;
         for (TStore tStore : lists) {
-            long l = DateUtil.betweenDay(tStore.getCreateTime(), new Date(), true);
-            String startTime = tStore.getStartTime();
-            String endTime = tStore.getEndTime();
-            String s = startTime.split(":")[0];
-            String s1 = endTime.split(":")[1];
-            Integer integer = Integer.valueOf(s);
-            Integer integer1 = Integer.valueOf(s1);
-            Integer a =0;
-            if(integer==0 && integer1==0){
-                a=24;
-            }else {
-                a= integer1-integer;
-            }
-            l1 += l * a;
+            l1 += getStoreOperatingHours(tStore, new Date());
         }
         map.put("allHour",l1);
         return map;
@@ -1644,7 +1729,3 @@
         return map1;
     }
 }
-
-
-
-
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TAppUserController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TAppUserController.java
index a456f51..dee2851 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TAppUserController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TAppUserController.java
@@ -92,6 +92,7 @@
         model.addAttribute("roleType",roleType);
         model.addAttribute("sales",deptid);
         model.addAttribute("list",list);
+        model.addAttribute("isSuperAdmin", "admin".equalsIgnoreCase(UserExt.getUser().getAccount()));
         return PREFIX + "TAppUser.html";
     }
     /**
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java
index 9221d31..994d965 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCompetitionController.java
@@ -24,7 +24,9 @@
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.InitBinder;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -34,6 +36,7 @@
 import javax.jws.soap.SOAPBinding;
 import javax.servlet.http.HttpServletResponse;
 import java.io.OutputStream;
+import java.beans.PropertyEditorSupport;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -62,7 +65,50 @@
     private ICityService cityService;
 
     /**
-     * 导出赛事已报名用户列表
+     * 兼容活动表单提交的日期时间格式。
+     *
+     * @param binder Spring Web 数据绑定器
+     */
+    @InitBinder
+    public void initCompetitionDateBinder(WebDataBinder binder) {
+        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
+            @Override
+            public void setAsText(String text) throws IllegalArgumentException {
+                if (ToolUtil.isEmpty(text)) {
+                    setValue(null);
+                    return;
+                }
+                Date parsedDate = parseCompetitionDate(text);
+                if (parsedDate == null) {
+                    throw new IllegalArgumentException("日期格式应为yyyy-MM-dd HH:mm或yyyy-MM-dd");
+                }
+                setValue(parsedDate);
+            }
+        });
+    }
+
+    /**
+     * 将活动表单日期文本解析为日期对象。
+     *
+     * @param value 日期文本
+     * @return 解析后的日期;格式不匹配时返回 {@code null}
+     */
+    private Date parseCompetitionDate(String value) {
+        String[] patterns = {"yyyy-MM-dd HH:mm", "yyyy-MM-dd"};
+        for (String pattern : patterns) {
+            try {
+                SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
+                dateFormat.setLenient(false);
+                return dateFormat.parse(value);
+            } catch (ParseException ignored) {
+                // 尝试下一个约定格式。
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 导出活动已报名用户列表
      */
 
     @RequestMapping(value = "/export")
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TFinanceController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TFinanceController.java
index 0048826..ae350fb 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TFinanceController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TFinanceController.java
@@ -26,6 +26,7 @@
 import com.dsh.guns.core.util.ToolUtil;
 import com.dsh.guns.modular.system.model.*;
 import com.dsh.guns.modular.system.service.*;
+import com.dsh.guns.modular.system.util.ResultUtil;
 import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
 import com.sun.org.apache.bcel.internal.generic.NEW;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -77,69 +78,68 @@
     private SiteClient siteClient;
 
 
-    /**
-     * 跳转到充值记录页面
+    /*
+     * 充值记录功能已下线,保留原实现以便后续恢复。
+     *
+     * @RequestMapping("/rechargeRecords")
+     * public String index(Model model) {
+     *     List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0));
+     *     model.addAttribute("list",list);
+     *     Integer objectType = UserExt.getUser().getObjectType();
+     *     Integer objectId = UserExt.getUser().getObjectId();
+     *     model.addAttribute("userType",objectType);
+     *     String roleid = UserExt.getUser().getRoleid();
+     *     model.addAttribute("objectType",objectType);
+     *     return PREFIX + "RechargeRecords.html";
+     * }
+     *
+     * @RequestMapping(value = "/listAll")
+     * @ResponseBody
+     * public List<RechargeRecordsVO> list(String province, String city, String name, String phone, String time, Integer type) {
+     *     RechargeRecordsQuery coachQuery = new RechargeRecordsQuery();
+     *     Region provinceCode = regionService.getOne(new QueryWrapper<Region>().eq("code", province));
+     *     Region cityCode = regionService.getOne(new QueryWrapper<Region>().eq("code", city));
+     *     if (provinceCode != null) {
+     *         coachQuery.setProvince(provinceCode.getName());
+     *     } else {
+     *         coachQuery.setProvince(province);
+     *     }
+     *     if (cityCode != null) {
+     *         coachQuery.setCity(cityCode.getName());
+     *     } else {
+     *         coachQuery.setCity(city);
+     *     }
+     *     coachQuery.setName(name);
+     *     coachQuery.setPhone(phone);
+     *     coachQuery.setTime(time);
+     *     coachQuery.setType(type);
+     *     return financeClient.rechargeList(coachQuery);
+     * }
+     *
+     * @RequestMapping(value = "/getAmount")
+     * @ResponseBody
+     * public BigDecimal getAmount(String province, String city, String name, String phone, String time, Integer type) {
+     *     RechargeRecordsQuery coachQuery = new RechargeRecordsQuery();
+     *     coachQuery.setProvince(province);
+     *     coachQuery.setCity(city);
+     *     coachQuery.setName(name);
+     *     coachQuery.setPhone(phone);
+     *     coachQuery.setTime(time);
+     *     coachQuery.setType(type);
+     *     List<RechargeRecordsVO> rechargeRecordsVOS = financeClient.rechargeList(coachQuery);
+     *     BigDecimal total = new BigDecimal("0.00");
+     *     for (RechargeRecordsVO rechargeRecordsVO : rechargeRecordsVOS) {
+     *         total = total.add(rechargeRecordsVO.getAmount());
+     *     }
+     *     return total;
+     * }
      */
-    @RequestMapping("/rechargeRecords")
-    public String index(Model model) {
-        List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0));
-        model.addAttribute("list",list);
-        Integer objectType = UserExt.getUser().getObjectType();
-        Integer objectId = UserExt.getUser().getObjectId();
-        model.addAttribute("userType",objectType);
-        String roleid = UserExt.getUser().getRoleid();
-        model.addAttribute("objectType",objectType);
-        return PREFIX + "RechargeRecords.html";
-    }
-    /**
-     * 获取充值记录
-     */
-    @RequestMapping(value = "/listAll")
-    @ResponseBody
-    public List<RechargeRecordsVO> list(String province, String city, String name, String phone,String time,Integer type) {
-        RechargeRecordsQuery coachQuery = new RechargeRecordsQuery();
-        Region provinceCode = regionService.getOne(new QueryWrapper<Region>().eq("code", province));
-        Region cityCode = regionService.getOne(new QueryWrapper<Region>().eq("code", city));
-        if (provinceCode!=null){
-            coachQuery.setProvince(provinceCode.getName());
-        }else{
-            coachQuery.setProvince(province);
-        }
-        if (cityCode!=null){
-            coachQuery.setCity(cityCode.getName());
-        }else{
-            coachQuery.setCity(city);
-        }
-        coachQuery.setName(name);
 
-        coachQuery.setPhone(phone);
-        coachQuery.setTime(time);
-        coachQuery.setType(type);
-        return financeClient.rechargeList(coachQuery);
-    }
-
-    /**
-     * 获取充值记录
-     */
-    @RequestMapping(value = "/getAmount")
+    /** 充值记录功能已下线,避免通过历史菜单或直接 URL 继续访问。 */
+    @RequestMapping({"/rechargeRecords", "/listAll", "/getAmount"})
     @ResponseBody
-    public BigDecimal getAmount(String province, String city, String name, String phone, String time, Integer type) {
-        RechargeRecordsQuery coachQuery = new RechargeRecordsQuery();
-        coachQuery.setProvince(province);
-        coachQuery.setCity(city);
-        coachQuery.setName(name);
-        coachQuery.setPhone(phone);
-        coachQuery.setTime(time);
-        coachQuery.setType(type);
-        List<RechargeRecordsVO> rechargeRecordsVOS = financeClient.rechargeList(coachQuery);
-        BigDecimal total = new BigDecimal("0.00");
-        BigDecimal result = new BigDecimal("0.00");
-        for (RechargeRecordsVO rechargeRecordsVO : rechargeRecordsVOS) {
-            BigDecimal amount = rechargeRecordsVO.getAmount();
-            total = total.add(amount); // 将新的值赋给total
-            result = result.add(amount); // 将新的值赋给result
-        }
-        return total;
+    public ResultUtil rechargeRecordsUnavailable() {
+        return ResultUtil.error("充值记录功能暂不提供");
     }
     /**
      * 获取报名订单统计数据
@@ -440,8 +440,9 @@
                         if(null == competition1){
                             continue;
                         }
-                        if (!competition1.getStoreId().equals("")){
-                            String[] split = competition1.getStoreId().split(",");
+                        String competitionStoreIds = resolveCompetitionStoreIds(competition, competition1);
+                        if (ToolUtil.isNotEmpty(competitionStoreIds)){
+                            String[] split = competitionStoreIds.split(",");
                             List<Integer> list = new ArrayList<>();
                             for (String s : split) {
                                 list.add(Integer.valueOf(s));
@@ -726,8 +727,9 @@
                     if(null == competition1){
                         continue;
                     }
-                    if (!competition1.getStoreId().equals("")){
-                        String[] split = competition1.getStoreId().split(",");
+                    String competitionStoreIds = resolveCompetitionStoreIds(competition, competition1);
+                    if (ToolUtil.isNotEmpty(competitionStoreIds)){
+                        String[] split = competitionStoreIds.split(",");
                         List<Integer> list = new ArrayList<>();
                         for (String s : split) {
                             list.add(Integer.valueOf(s));
@@ -898,10 +900,20 @@
         return coursePackagePaymentClient.listAllRegister(query);
     }
 
+    /**
+     * 获取收入记录对应的门店归属;新订单使用下单快照,兼容未回填的历史订单。
+     *
+     * @param paymentCompetition 活动支付记录
+     * @param competition 活动当前信息
+     * @return 逗号分隔的门店 ID 列表
+     */
+    private String resolveCompetitionStoreIds(PaymentCompetition paymentCompetition, Competition competition) {
+        if (ToolUtil.isNotEmpty(paymentCompetition.getCompetitionStoreIds())) {
+            return paymentCompetition.getCompetitionStoreIds();
+        }
+        return competition.getStoreId();
+    }
 
 
 }
-
-
-
 
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TNoticController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TNoticController.java
index db57607..d209531 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TNoticController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TNoticController.java
@@ -157,7 +157,9 @@
         if(ToolUtil.isNotEmpty(type)){
             tNoticeLambdaQueryWrapper.eq(TNotice::getUpOrDown,type);
         }
-        tNoticeLambdaQueryWrapper.eq(TNotice::getState,1);
+        tNoticeLambdaQueryWrapper.eq(TNotice::getState,1)
+                .orderByDesc(TNotice::getInsertTime)
+                .orderByDesc(TNotice::getId);
         Page<TNotice> page1 = noticeService.page(page, tNoticeLambdaQueryWrapper);
         return  super.packForBT(page1);
     }
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 ed9a805..b82a8d4 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
@@ -52,6 +52,8 @@
 @RequestMapping("/tPayHuimin")
 public class TPayHuiminController extends BaseController {
 
+    private static final Integer GIFT_PAYMENT_TYPE = 3;
+
     private String PREFIX = "/system/tPayHuimin/";
 
     @Autowired
@@ -235,23 +237,24 @@
                 item.setStoreName(sb.toString());
             });
         }
-        String[] titleArr = {"玩湃惠民卡名称", "玩湃惠民卡类型", "售卖金额", "所属运营商", "可用门店", "购买用户", "联系电话", "购买时间", "绑定人员", "已用次数", "有效期", "状态"};
+        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 ? "使用中" : "已退款";
+            values[i][2] = GIFT_PAYMENT_TYPE.equals(salesDetailVO.getPaymentType()) ? "赠送" : "售卖";
+            values[i][3] = salesDetailVO.getSalesMoney().toString();
+            values[i][4] = salesDetailVO.getOperatorName();
+            values[i][5] = salesDetailVO.getStoreName();
+            values[i][6] = salesDetailVO.getUserName();
+            values[i][7] = salesDetailVO.getPhone();
+            values[i][8] = DateUtil.format(salesDetailVO.getPaymentTime(), "yyyy-MM-dd HH:mm:ss");
+            values[i][9] = salesDetailVO.getStudentName();
+            values[i][10] = salesDetailVO.getUseTimes().toString();
+            values[i][11] = DateUtil.format(salesDetailVO.getEndTime(), "yyyy-MM-dd HH:mm:ss");
+            values[i][12] = salesDetailVO.getStatus() == 2 ? "使用中" : "已退款";
         }
         try {
             HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook("售卖明细", titleArr, values, null);
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java
index 0aec5ba..f6a8d6d 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java
@@ -508,7 +508,7 @@
 
     @RequestMapping(value = "/add")
     @ResponseBody
-    public Object list(TStore tStore,String time,String userName,String userPhone,String ids,Integer type,Integer yyId,String lat,String lon,String pCode1,String cCode1) {
+    public Object list(TStore tStore,String time,String ids,Integer type,Integer yyId,String lat,String lon,String pCode1,String cCode1) {
         try {
             if(yyId==null || type==1){
                 yyId=0;
@@ -569,20 +569,6 @@
             tStore.setOperatorId(yyId);
             tStore.setState(1);
             tStore.setCreateTime(new Date());
-            User user = new User();
-            List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getAccount, userPhone));
-            if(users.size()>0){
-                return "5001";
-            }
-            user.setAccount(userPhone);
-            user.setName(userName);
-            user.setRoleid("3");
-            user.setPhone(userPhone);
-            user.setPassword(SecureUtil.md5("a123456"));
-            user.setObjectType(3);
-            user.setStatus(1);
-            userMapper.insert(user);
-            tStore.setStoreStaffId(user.getId());
             tStore.setLon(lon);
             tStore.setLat(lat);
             if (yyId == null || yyId == 0){
@@ -602,7 +588,7 @@
             map1.put("location",tStore.getCity());
             map1.put("address",tStore.getAddress());
             map1.put("telephone",tStore.getPhone());
-            map1.put("linkman",userName);
+            map1.put("linkman",tStore.getName());
             map1.put("business_time","[{\"start_time\":\""+tStore.getStartTime()+"\",\"close_time\":\""+tStore.getEndTime()+"\"}]");
             map1.put("logo",tStore.getCoverDrawing());
             map1.put("remark",tStore.getIntroduce());
@@ -617,8 +603,6 @@
             Integer integer = Integer.valueOf(space_id);
             tStore.setId(integer);
             storeService.save(tStore);
-            user.setObjectId(tStore.getId());
-            userService.updateById(user);
             ArrayList<StoreConfig> storeConfigs = new ArrayList<>();
             for (int i = 1; i < 9; i++) {
                 StoreConfig storeConfig = new StoreConfig();
@@ -655,7 +639,7 @@
 
     @RequestMapping(value = "/update")
     @ResponseBody
-    public Object update(TStore tStore,String time,String userName,String userPhone,String ids,Integer type,Integer yyId,String lat,String lon,String pCode1,String cCode1) {
+    public Object update(TStore tStore,String time,String ids,Integer type,Integer yyId,String lat,String lon,String pCode1,String cCode1) {
         try {
             TStore byIdc = storeService.getById(tStore.getId());
 
@@ -714,15 +698,6 @@
             if(ToolUtil.isEmpty(tStore.getCoverDrawing())){
                 tStore.setCoverDrawing(byIdc.getCoverDrawing());
             }
-            User user = userMapper.selectById(byIdc.getStoreStaffId());
-            List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getAccount, userPhone).ne(User::getId,tStore.getStoreStaffId()));
-            if(users.size()>0){
-                return "5001";
-            }
-            user.setAccount(userPhone);
-            user.setName(userName);
-            user.setPhone(userPhone);
-            userMapper.updateById(user);
             tStore.setLon(lon);
             tStore.setLat(lat);
             // 运营商编辑
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TStoredValueConfigController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TStoredValueConfigController.java
index 4fe42ed..71c6dea 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TStoredValueConfigController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TStoredValueConfigController.java
@@ -29,37 +29,37 @@
     private String PREFIX = "/system/storeValueConfig/";
     @Autowired
     private StoreValueConfigClient storeValueConfigClient;
-    /**
-     * 跳转储值管理页面
+    /*
+     * 储值管理功能已下线,保留原实现以便后续恢复。
+     *
+     * @RequestMapping("")
+     * public String index(Model model) {
+     *     StoredValueConfig storeValueConfig = storeValueConfigClient.getStoreValueConfig();
+     *     model.addAttribute("description", storeValueConfig.getDescription());
+     *     JSONObject jsonObject = new JSONObject(storeValueConfig.getContent());
+     *     JSONArray timeRulesArray = jsonObject.getJSONArray("time_rules");
+     *     model.addAttribute("content", jsonObject.toString());
+     *     if (timeRulesArray.length() > 0) {
+     *         JSONObject timeRule = timeRulesArray.getJSONObject(0);
+     *         model.addAttribute("time", timeRule.getString("startTime") + " - " + timeRule.getString("endTime"));
+     *     } else {
+     *         model.addAttribute("time", "");
+     *     }
+     *     return PREFIX + "StoreValueConfig.html";
+     * }
+     *
+     * @ResponseBody
+     * @RequestMapping(value = "/addStoreValueConfig")
+     * public ResultUtil addStoreValueConfig(@RequestBody StoredValueConfig storedValueConfig) {
+     *     storeValueConfigClient.addStoreValueConfig(storedValueConfig);
+     *     return ResultUtil.success();
+     * }
      */
-    @RequestMapping("")
-    public String index(Model model) {
-        StoredValueConfig storeValueConfig = storeValueConfigClient.getStoreValueConfig();
 
-        model.addAttribute("description",storeValueConfig.getDescription());
-        // 解析json串 获取时间
-        JSONObject jsonObject = new JSONObject(storeValueConfig.getContent());
-        JSONArray timeRulesArray = jsonObject.getJSONArray("time_rules");
-        model.addAttribute("content",jsonObject.toString());
-        if (timeRulesArray.length() > 0) {
-            JSONObject timeRule = timeRulesArray.getJSONObject(0);
-            String startTime = timeRule.getString("startTime");
-            String endTime = timeRule.getString("endTime");
-            model.addAttribute("time",startTime+" - " + endTime);
-            System.out.println("StartTime: " + startTime);
-            System.out.println("EndTime: " + endTime);
-        }else{
-            model.addAttribute("time","");
-        }
-        return PREFIX + "StoreValueConfig.html";
-    }
-    /**
-     *  添加储值规则
-     */
+    /** 储值管理功能已下线,避免通过历史菜单或直接 URL 继续访问。 */
     @ResponseBody
-    @RequestMapping(value = "/addStoreValueConfig")
-    public ResultUtil addStoreValueConfig(@RequestBody StoredValueConfig storedValueConfig) {
-        storeValueConfigClient.addStoreValueConfig(storedValueConfig);
-        return  ResultUtil.success();
+    @RequestMapping({"", "/addStoreValueConfig"})
+    public ResultUtil storeValueConfigUnavailable() {
+        return ResultUtil.error("储值管理功能暂不提供");
     }
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TicketController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TicketController.java
index 28fb52d..5f1507c 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TicketController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TicketController.java
@@ -16,6 +16,7 @@
 import com.dsh.course.feignClient.activity.PointMercharsClient;
 import com.dsh.course.feignClient.activity.model.*;
 import com.dsh.guns.config.UserExt;
+import com.dsh.guns.modular.system.audit.ManagementAuditWriter;
 import com.dsh.guns.core.base.tips.SuccessTip;
 import com.dsh.guns.core.common.constant.factory.PageFactory;
 import com.dsh.guns.core.util.ToolUtil;
@@ -36,10 +37,7 @@
 import javax.annotation.Resource;
 import java.io.IOException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -71,6 +69,8 @@
     private PointMercharsClient pointMercharsClient;
     @Autowired
     private StoreStaffClient storeStaffClient;
+    @Resource
+    private ManagementAuditWriter auditWriter;
 
     /**
      * 跳转到优惠券管理首页
@@ -122,8 +122,53 @@
     @RequestMapping("/changeState")
     @ResponseBody
     public Object changeState(@RequestBody CoachChangeStateVO vo){
-        pointMercharsClient.changeState(vo);
-        return ResultUtil.success();
+        List<Map<String, Object>> before = new ArrayList<Map<String, Object>>();
+        for (Integer id : vo.getIds()) {
+            PointsMerchandise ticket = pointMercharsClient.getById(id);
+            Map<String, Object> item = new HashMap<String, Object>();
+            item.put("id", id);
+            item.put("name", ticket == null ? null : ticket.getName());
+            item.put("state", ticket == null ? null : ticket.getState());
+            before.add(item);
+        }
+        try {
+            pointMercharsClient.changeState(vo);
+            List<Map<String, Object>> after = new ArrayList<Map<String, Object>>();
+            for (Map<String, Object> item : before) {
+                Map<String, Object> changed = new HashMap<String, Object>(item);
+                changed.put("state", vo.getState());
+                after.add(changed);
+            }
+            appendTicketStateAudit(vo, before, after, "SUCCESS", null);
+            return ResultUtil.success();
+        } catch (RuntimeException ex) {
+            appendTicketStateAudit(vo, before, null, "FAIL", ex.getMessage());
+            throw ex;
+        }
+    }
+
+    private void appendTicketStateAudit(CoachChangeStateVO request, Object before, Object after, String result, String error) {
+        try {
+            Map<String, Object> audit = new HashMap<String, Object>();
+            audit.put("sourceService", "mb-cloud-management");
+            audit.put("sourceType", "HTTP");
+            audit.put("operationType", "STATUS_CHANGE");
+            audit.put("riskLevel", "CRITICAL");
+            audit.put("operationName", "管理员修改门票上下架状态");
+            audit.put("requestMethod", "POST");
+            audit.put("requestUri", "/ticket/changeState");
+            audit.put("requestParams", "ids=" + request.getIds() + ", targetState=" + request.getState());
+            audit.put("beforeData", JSONObject.toJSONString(before));
+            audit.put("afterData", JSONObject.toJSONString(after));
+            audit.put("userId", UserExt.getUser() == null ? null : UserExt.getUser().getId());
+            audit.put("userAccount", UserExt.getUser() == null ? null : UserExt.getUser().getAccount());
+            audit.put("result", result);
+            audit.put("errorMessage", error);
+            audit.put("createdAt", new Date());
+            auditWriter.append(audit);
+        } catch (Exception ignored) {
+            // 审计故障不影响实际的门票状态变更;由网关审计作为兜底记录。
+        }
     }
     /**
      * 获取门票列表
@@ -357,28 +402,78 @@
         return new SuccessTip<>();
     }
     /**
-     *  上下架处理操作
-     * @return
+     * 根据管理员选择的入园方式核销门票,并写入管理端审计日志。
+     *
+     * @param id 用户已购门票记录ID
+     * @param goType 入园方式:1=手环,2=门票核销
      */
     @RequestMapping("/writeOff")
     @ResponseBody
-    public Object writeOff(String id) {
+    public Object writeOff(String id, Integer goType) {
+        if (!Integer.valueOf(1).equals(goType) && !Integer.valueOf(2).equals(goType)) {
+            return ResultUtil.error("入园方式参数不正确");
+        }
         Long aLong = Long.valueOf(id);
         WriteOffDTO dto = new WriteOffDTO();
-        // 核销人员id
+        // 核销人员ID与所属门店由登录上下文确定,不能由前端传入。
         Integer objectId = UserExt.getUser().getId();
         if (UserExt.getUser().getObjectType() == 1){
             dto.setVerifiStoreId(null);
         }else if (UserExt.getUser().getObjectType() == 2){
-            storeService.getOne(new QueryWrapper<TStore>().eq("cityManagerId",objectId));
+            TStore store = storeService.getOne(new QueryWrapper<TStore>().eq("cityManagerId", objectId));
+            dto.setVerifiStoreId(store == null ? null : store.getId());
         }else{
             TStoreStaff storeByStoreStaffId = storeStaffClient.getStoreByStoreStaffId(objectId);
             dto.setVerifiStoreId(storeByStoreStaffId.getStoreId());
         }
         dto.setId(aLong);
+        dto.setGoType(goType);
         dto.setVerificationUserId(objectId);
-        pointMercharsClient.writeOff(dto);
-        return new SuccessTip<>();
+        try {
+            pointMercharsClient.writeOff(dto);
+            appendTicketWriteOffAudit(dto, "SUCCESS", null);
+            return new SuccessTip<>();
+        } catch (RuntimeException ex) {
+            appendTicketWriteOffAudit(dto, "FAIL", ex.getMessage());
+            throw ex;
+        }
+    }
+
+    /** 记录管理员核销门票及所选入园方式,审计失败不影响正常业务流程。 */
+    private void appendTicketWriteOffAudit(WriteOffDTO dto, String result, String errorMessage) {
+        try {
+            Map<String, Object> beforeData = new HashMap<>();
+            beforeData.put("id", dto.getId());
+            beforeData.put("status", "待核销");
+
+            Map<String, Object> afterData = new HashMap<>(beforeData);
+            afterData.put("status", "已核销");
+            afterData.put("goType", dto.getGoType());
+            afterData.put("goTypeName", dto.getGoType() == 1 ? "手环" : "门票核销");
+            afterData.put("verificationUserId", dto.getVerificationUserId());
+            afterData.put("verifiStoreId", dto.getVerifiStoreId());
+
+            Map<String, Object> audit = new HashMap<>();
+            audit.put("traceId", UUID.randomUUID().toString().replace("-", ""));
+            audit.put("sourceService", "mb-cloud-management");
+            audit.put("sourceType", "HTTP");
+            audit.put("operationType", "STATUS_CHANGE");
+            audit.put("riskLevel", "CRITICAL");
+            audit.put("operationName", "管理员核销门票");
+            audit.put("requestMethod", "POST");
+            audit.put("requestUri", "/ticket/writeOff");
+            audit.put("requestParams", "id=" + dto.getId() + ", goType=" + dto.getGoType());
+            audit.put("beforeData", JSONObject.toJSONString(beforeData));
+            audit.put("afterData", JSONObject.toJSONString(afterData));
+            audit.put("userId", UserExt.getUser() == null ? null : UserExt.getUser().getId());
+            audit.put("userAccount", UserExt.getUser() == null ? null : UserExt.getUser().getAccount());
+            audit.put("result", result);
+            audit.put("errorMessage", errorMessage);
+            audit.put("createdAt", new Date());
+            auditWriter.append(audit);
+        } catch (Exception ignored) {
+            // 审计不可用时不阻断门票核销,网关审计会记录请求作为兜底。
+        }
     }
 
     /**
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/BallController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/BallController.java
index c03fea9..cf2ee0f 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/BallController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/BallController.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.dsh.course.dto.JsDto;
 import com.dsh.course.dto.StudentQeryDto;
 import com.dsh.course.entity.SiteLock;
@@ -23,12 +24,17 @@
 import com.dsh.guns.config.UserExt;
 import com.dsh.guns.core.base.controller.BaseController;
 import com.dsh.guns.core.util.ToolUtil;
+import com.dsh.guns.modular.system.audit.ManagementAuditWriter;
 import com.dsh.guns.modular.system.controller.util.MD5;
 import com.dsh.guns.modular.system.model.*;
 import com.dsh.guns.modular.system.model.dto.*;
 import com.dsh.guns.modular.system.service.*;
 import com.dsh.guns.modular.system.util.*;
 import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,8 +47,12 @@
 
 import javax.annotation.Resource;
 import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletResponse;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -90,6 +100,9 @@
     @Autowired
     private AppUserClient appUserClient;
 
+    @Resource
+    private ManagementAuditWriter auditWriter;
+
     @RequestMapping("/tolist")
     public String tolist(Model model) {
         List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0));
@@ -114,15 +127,93 @@
     @RequestMapping("/selectJoin")
     @ResponseBody
     public ResultUtil join(@RequestBody MethodDto method) {
+        if (method == null || method.getId() == null) {
+            return ResultUtil.error("门票记录不能为空");
+        }
+        SiteBooking before = iSiteBookingService.getById(method.getId());
+        if (before == null) {
+            return ResultUtil.error("门票记录不存在");
+        }
+        Integer previousStatus = before.getStatus();
+        if (!Objects.equals(previousStatus, 1) && !Objects.equals(previousStatus, 4)) {
+            return ResultUtil.error("当前门票状态不能确认到店");
+        }
 
-        System.out.println("============" + method);
+        // 待核销正常确认到店;已过期但运营确认用户实际入场时,直接人工完成。
+        Integer targetStatus = Objects.equals(previousStatus, 4) ? 3 : 2;
         SiteBooking siteBooking = new SiteBooking();
-        siteBooking.setStatus(2);
+        siteBooking.setStatus(targetStatus);
         siteBooking.setId(method.getId());
         siteBooking.setGoType(method.getMethod());
-        iSiteBookingService.updateById(siteBooking);
+        try {
+            // 以修改前状态作为条件,避免并发操作覆盖其他状态变更。
+            boolean updated = iSiteBookingService.update(siteBooking,
+                    new LambdaUpdateWrapper<SiteBooking>()
+                            .eq(SiteBooking::getId, before.getId())
+                            .eq(SiteBooking::getStatus, previousStatus));
+            if (!updated) {
+                appendTicketStatusAudit(before, targetStatus, method.getMethod(), "FAIL", "门票状态更新失败");
+                return ResultUtil.error("确认到店失败");
+            }
+            appendTicketStatusAudit(before, targetStatus, method.getMethod(), "SUCCESS", null);
+        } catch (RuntimeException ex) {
+            appendTicketStatusAudit(before, targetStatus, method.getMethod(), "FAIL", ex.getMessage());
+            throw ex;
+        }
 
         return new ResultUtil<>(0, 0, "到店成功", null, null);
+    }
+
+    /** 记录运营管理员人工确认到店导致的门票状态变更。 */
+    private void appendTicketStatusAudit(SiteBooking before, Integer targetStatus, Integer goType,
+                                         String result, String errorMessage) {
+        try {
+            Map<String, Object> beforeData = new HashMap<>();
+            beforeData.put("id", before.getId());
+            beforeData.put("orderNo", before.getOrderNo());
+            beforeData.put("status", before.getStatus());
+            beforeData.put("statusName", ticketStatusName(before.getStatus()));
+
+            Map<String, Object> afterData = new HashMap<>(beforeData);
+            afterData.put("status", targetStatus);
+            afterData.put("statusName", ticketStatusName(targetStatus));
+            afterData.put("goType", goType);
+
+            Map<String, Object> audit = new HashMap<>();
+            audit.put("traceId", UUID.randomUUID().toString().replace("-", ""));
+            audit.put("sourceService", "mb-cloud-management");
+            audit.put("sourceType", "HTTP");
+            audit.put("operationType", "STATUS_CHANGE");
+            audit.put("riskLevel", "CRITICAL");
+            audit.put("operationName", "运营管理员人工修改门票状态");
+            audit.put("requestMethod", "POST");
+            audit.put("requestUri", "/ball/selectJoin");
+            audit.put("requestParams", "id=" + before.getId() + ", goType=" + goType + ", targetStatus=" + targetStatus);
+            audit.put("beforeData", com.alibaba.fastjson.JSONObject.toJSONString(beforeData));
+            audit.put("afterData", com.alibaba.fastjson.JSONObject.toJSONString(afterData));
+            audit.put("userId", UserExt.getUser() == null ? null : UserExt.getUser().getId());
+            audit.put("userAccount", UserExt.getUser() == null ? null : UserExt.getUser().getAccount());
+            audit.put("result", result);
+            audit.put("errorMessage", errorMessage);
+            // 审计表的 createdAt 即本次管理员操作时间。
+            audit.put("createdAt", new Date());
+            auditWriter.append(audit);
+        } catch (Exception ignored) {
+            // 审计失败不能阻断实际到店确认,网关日志可作为兜底。
+        }
+    }
+
+    private String ticketStatusName(Integer status) {
+        if (status == null) return "未知";
+        switch (status) {
+            case 0: return "待支付";
+            case 1: return "待核销";
+            case 2: return "已到店";
+            case 3: return "已完成";
+            case 4: return "已过期";
+            case 5: return "已取消";
+            default: return "未知";
+        }
     }
 
 
@@ -1105,6 +1196,67 @@
     @RequestMapping("/yuyuelist")
     @ResponseBody
     public List<Map<String, Object>> yuyuelist(BookingQuery bookingQuery) {
+        return queryBookingOrders(bookingQuery);
+    }
+
+    /**
+     * 导出当前筛选条件下的全部预约记录,不受列表分页影响。
+     */
+    @RequestMapping("/yuyueexport")
+    public void exportYuyue(BookingQuery bookingQuery, HttpServletResponse response) throws IOException {
+        List<Map<String, Object>> orders = queryBookingOrders(bookingQuery);
+        String[] headers = {"序号", "所在省", "所在市", "预约门店", "入场方式", "预约场地", "姓名", "联系电话",
+                "预约时间段", "支付流水号", "支付方式", "金额", "状态"};
+
+        // 线上运行环境使用的是旧版 POI 核心包,使用 HSSF 保持依赖兼容;
+        // 超过单 Sheet 上限的数据拆分到多个工作表,确保导出全部命中记录。
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        try {
+            final int maxDataRowsPerSheet = 60000;
+            int sheetCount = Math.max(1, (orders.size() + maxDataRowsPerSheet - 1) / maxDataRowsPerSheet);
+            for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++) {
+                Sheet sheet = workbook.createSheet(sheetCount == 1 ? "预约管理" : "预约管理" + (sheetIndex + 1));
+                Row header = sheet.createRow(0);
+                for (int i = 0; i < headers.length; i++) {
+                    header.createCell(i).setCellValue(headers[i]);
+                    sheet.setColumnWidth(i, i == 8 ? 28 * 256 : 18 * 256);
+                }
+                int start = sheetIndex * maxDataRowsPerSheet;
+                int end = Math.min(start + maxDataRowsPerSheet, orders.size());
+                for (int rowIndex = start; rowIndex < end; rowIndex++) {
+                    Map<String, Object> order = orders.get(rowIndex);
+                    Row row = sheet.createRow(rowIndex - start + 1);
+                    String[] values = {
+                            valueOf(order.get("id")), valueOf(order.get("province")), valueOf(order.get("city")),
+                            valueOf(order.get("name")), targetAudienceName(order.get("targetAudience")),
+                            valueOf(order.get("siteName")), valueOf(order.get("booker")), valueOf(order.get("phone")),
+                            valueOf(order.get("times")), valueOf(order.get("payOrderNo")), valueOf(order.get("payType")),
+                            moneyText(order.get("payType"), order.get("payMoney")), ticketStatusName(toInteger(order.get("status")))
+                    };
+                    for (int columnIndex = 0; columnIndex < values.length; columnIndex++) {
+                        Cell cell = row.createCell(columnIndex);
+                        cell.setCellValue(values[columnIndex]);
+                    }
+                }
+            }
+
+            String fileName = "预约管理_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".xls";
+            response.reset();
+            response.setContentType("application/vnd.ms-excel");
+            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
+            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''"
+                    + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replace("+", "%20"));
+            try (OutputStream output = response.getOutputStream()) {
+                workbook.write(output);
+                output.flush();
+            }
+        } finally {
+            // HSSFWorkbook 由旧版 POI 提供,不调用新版 Workbook 的 close API。
+        }
+    }
+
+    /** 列表和导出共用同一查询与数据展示转换,保证权限范围和筛选条件一致。 */
+    private List<Map<String, Object>> queryBookingOrders(BookingQuery bookingQuery) {
         Integer objectType = UserExt.getUser().getObjectType();
 
         if (objectType == 2) {
@@ -1159,6 +1311,31 @@
         return orders;
     }
 
+    private String targetAudienceName(Object targetAudience) {
+        Integer value = toInteger(targetAudience);
+        if (Objects.equals(value, 1)) return "订场";
+        if (Objects.equals(value, 2)) return "散客";
+        return "";
+    }
+
+    private String moneyText(Object payType, Object payMoney) {
+        if (payMoney == null) return "";
+        return valueOf(payMoney) + ("玩湃币".equals(valueOf(payType)) ? "币" : "元");
+    }
+
+    private Integer toInteger(Object value) {
+        if (value == null || value.toString().trim().isEmpty()) return null;
+        try {
+            return Integer.valueOf(value.toString());
+        } catch (NumberFormatException ignored) {
+            return null;
+        }
+    }
+
+    private String valueOf(Object value) {
+        return value == null ? "" : String.valueOf(value);
+    }
+
 
     @RequestMapping("/addjs")
     @ResponseBody
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
index d20430b..373d8b5 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/system/UserMgrController.java
@@ -34,10 +34,14 @@
 import com.dsh.guns.modular.system.util.ResultUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.Model;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.beans.propertyeditors.CustomNumberEditor;
 
 import javax.naming.NoPermissionException;
 import javax.servlet.http.HttpServletResponse;
@@ -57,6 +61,12 @@
 
     private static String PREFIX = "/system/user/";
 
+    /** 多选框未选择时会提交空字符串;将其转换为空值,避免绑定 List<Integer> 时抛 NumberFormatException。 */
+    @InitBinder
+    public void initBinder(WebDataBinder binder) {
+        binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true));
+    }
+
     @Autowired
     private GunsProperties gunsProperties;
 
@@ -75,6 +85,7 @@
     @RequestMapping("")
     public String index(Model model) {
         model.addAttribute("language",UserExt.getLanguage());
+        model.addAttribute("isSuperAdmin", "admin".equalsIgnoreCase(UserExt.getUser().getAccount()));
         return PREFIX + "user.html";
     }
 
@@ -95,7 +106,20 @@
         // 部门列表
         List<Dept> depts = deptService.list(new QueryWrapper<>());
         model.addAttribute("depts",depts);
+        model.addAttribute("stores", availableStores());
         return PREFIX + "user_add.html";
+    }
+
+    private List<TStore> availableStores() {
+        LambdaQueryWrapper<TStore> query = new LambdaQueryWrapper<TStore>().eq(TStore::getState, 1);
+        Integer objectType = UserExt.getUser().getObjectType();
+        Integer objectId = UserExt.getUser().getObjectId();
+        if (Integer.valueOf(2).equals(objectType)) {
+            query.eq(TStore::getOperatorId, objectId);
+        } else if (Integer.valueOf(3).equals(objectType)) {
+            query.eq(TStore::getId, objectId);
+        }
+        return storeService.list(query);
     }
 
     /**
@@ -128,6 +152,8 @@
         User user = this.userService.getById(userId);
         Role role = roleService.getById(user.getRoleid());
         Dept dept = deptService.getById(user.getDeptid());
+        user.setPhone(maskPhone(user.getPhone()));
+        user.setIdCard(maskIdCard(user.getIdCard()));
         model.addAttribute(user);
         if(role==null){
             model.addAttribute("roleName", "");
@@ -153,8 +179,21 @@
         // 部门列表
         List<Dept> depts = deptService.list(new QueryWrapper<>());
         model.addAttribute("depts",depts);
+        model.addAttribute("stores", availableStores());
+        // 回显同时兼容新关联表、sys_user 旧归属字段和 t_store.storeStaffId 旧数据。
+        List<Integer> selectedStoreIds = userMapper.getStoreIdsByUserId(userId);
+        model.addAttribute("selectedStoreIds", selectedStoreIds.stream()
+                .map(String::valueOf).collect(Collectors.joining(",")));
         model.addAttribute("type",type);
         return PREFIX + "user_edit.html";
+    }
+
+    /** 编辑页异步读取已关联门店,避免模板渲染集合造成多选回显丢失。 */
+    @GetMapping("/storeIds/{userId}")
+    @ResponseBody
+    public List<Integer> getStoreIds(@PathVariable Integer userId) {
+        assertAuth(userId);
+        return userMapper.getStoreIdsByUserId(userId);
     }
 
     /**
@@ -169,6 +208,8 @@
         User user = this.userService.getById(userId);
         Role role = roleService.getById(user.getRoleid());
         Dept dept = deptService.getById(user.getDeptid());
+        user.setPhone(maskPhone(user.getPhone()));
+        user.setIdCard(maskIdCard(user.getIdCard()));
         model.addAttribute(user);
         model.addAttribute("roleName", role.getName());
         if(dept==null){
@@ -213,6 +254,8 @@
 
     @Autowired
     private IStoreService storeService;
+    @Autowired
+    private UserMapper userMapper;
     /**
      * 查询管理员列表
      */
@@ -293,12 +336,12 @@
             throw new GunsException(BizExceptionEnum.REQUEST_NULL);
         }
 
-        // 判断账号是否重复
-        User theUser = new User();
-        if (user.getPhone()!=""){
-         theUser = userService.getByAccount(user.getPhone());
+        // 手机号既是登录账号,必须在 sys_user 中唯一;使用内容判断,不能使用 != 比较字符串引用。
+        if (StringUtils.isEmpty(user.getPhone())) {
+            return 5002;
         }
-        if (theUser != null){
+        User theUser = userService.getOne(new QueryWrapper<User>().eq("phone", user.getPhone()));
+        if (theUser != null || userService.getByAccount(user.getPhone()) != null){
             return 5001;
         }
 
@@ -308,7 +351,7 @@
         user.setCreatetime(new Date());
         User objectUser = UserFactory.createUser(user);
 
-        if (user.getRoleid().equals("")){
+        if (StringUtils.isEmpty(user.getRoleid())){
             objectUser.setObjectType(2);
         }else {
             objectUser.setObjectType(Integer.valueOf(user.getRoleid()));
@@ -326,8 +369,28 @@
         objectUser.setStatus(1);
         objectUser.setPassword(SecureUtil.md5("a123456"));
         objectUser.setCreatetime(new Date());
+        List<TStore> assignedStores = new ArrayList<TStore>();
+        if (user.getStoreIds() != null && !user.getStoreIds().isEmpty()) {
+            List<Integer> storeIds = user.getStoreIds().stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
+            if (storeIds.isEmpty()) return ResultUtil.error("请选择有效门店");
+            Integer currentType = UserExt.getUser().getObjectType();
+            Integer currentObjectId = UserExt.getUser().getObjectId();
+            for (Integer storeId : storeIds) {
+                TStore store = storeService.getById(storeId);
+                if (store == null || !Integer.valueOf(1).equals(store.getState())) return ResultUtil.error("所选门店不存在或已停用");
+                if ((Integer.valueOf(2).equals(currentType) && !currentObjectId.equals(store.getOperatorId()))
+                        || (Integer.valueOf(3).equals(currentType) && !currentObjectId.equals(store.getId()))) {
+                    return ResultUtil.error("所选门店不在当前账号的管理范围内");
+                }
+                assignedStores.add(store);
+            }
+            // 首个门店同步写入旧字段,保证既有权限、数据查询和登录逻辑无需改造。
+            TStore primaryStore = assignedStores.get(0);
+            objectUser.setObjectType(3);
+            objectUser.setRoleid("3");
+            objectUser.setObjectId(primaryStore.getId());
         // 运营商添加员工
-        if (UserExt.getUser().getObjectType() == 2){
+        } else if (UserExt.getUser().getObjectType() == 2){
             objectUser.setObjectType(UserExt.getUser().getObjectType());
             objectUser.setRoleid("2");
             objectUser.setObjectId(UserExt.getUser().getObjectId());
@@ -340,6 +403,15 @@
         }
         objectUser.setVersion(UserExt.getUser().getId());
         this.userService.save(objectUser);
+        if (!assignedStores.isEmpty()) {
+            userMapper.deleteStoreRelations(objectUser.getId());
+            userMapper.insertStoreRelations(objectUser.getId(), assignedStores.stream().map(TStore::getId).collect(Collectors.toList()));
+            // 各所选门店同步负责人账号;旧系统仍可通过 storeStaffId 查询主负责人。
+            for (TStore store : assignedStores) {
+                store.setStoreStaffId(objectUser.getId());
+                storeService.updateById(store);
+            }
+        }
         return SUCCESS_TIP;
     }
 
@@ -351,13 +423,17 @@
     @RequestMapping("/edit")
     @BussinessLog(value = "修改管理员", key = "account", dict = UserDict.class)
     @ResponseBody
+    @Transactional(rollbackFor = Exception.class)
     public Object edit(@Valid UserDto user, BindingResult result) throws NoPermissionException {
         if (result.hasErrors()) {
             throw new GunsException(BizExceptionEnum.REQUEST_NULL);
         }
         User oldUser = userService.getById(user.getId());
         // 判断是否更改电话
-        if (!oldUser.getPhone().equals(user.getPhone())){
+        if (user.getPhone() != null && user.getPhone().contains("*")) {
+            // The edit view displays a masked phone. Treat an unchanged masked
+            // value as "keep original", never as a value to persist.
+        } else if (!oldUser.getPhone().equals(user.getPhone())){
             User phone = userService.getOne(new QueryWrapper<User>().eq("phone", user.getPhone()));
             if (phone == null){
                 oldUser.setPhone(user.getPhone());
@@ -368,15 +444,60 @@
         oldUser.setName(user.getName());
         oldUser.setBirthday(user.getBirthday());
         oldUser.setDeptid(user.getDeptid());
-        oldUser.setIdCard(user.getIdCard());
+        if (user.getIdCard() == null || !user.getIdCard().contains("*")) oldUser.setIdCard(user.getIdCard());
         oldUser.setSex(user.getSex());
         oldUser.setEmail(user.getEmail());
         if (user.getAvatar()!=null && (!user.getAvatar().equals("")))
         oldUser.setAvatar(user.getAvatar());
+        if (user.getStoreIds() != null) {
+            List<TStore> assignedStores = validateStores(user.getStoreIds());
+            if (assignedStores == null) return ResultUtil.error("所选门店不存在、已停用或不在当前账号管理范围内");
+            userMapper.deleteStoreRelations(oldUser.getId());
+            if (!assignedStores.isEmpty()) {
+                oldUser.setObjectType(3);
+                oldUser.setObjectId(assignedStores.get(0).getId());
+                oldUser.setRoleid("3");
+                userMapper.insertStoreRelations(oldUser.getId(), assignedStores.stream().map(TStore::getId).collect(Collectors.toList()));
+                for (TStore store : assignedStores) {
+                    store.setStoreStaffId(oldUser.getId());
+                    storeService.updateById(store);
+                }
+            }
+        }
         this.userService.updateById(oldUser);
         return SUCCESS_TIP;
     }
 
+    private String maskPhone(String value) {
+        if (value == null) return null;
+        return value.length() <= 7 ? stars(value.length()) : value.substring(0, 3) + "****" + value.substring(7);
+    }
+
+    private String maskIdCard(String value) {
+        if (value == null) return null;
+        return value.length() <= 10 ? stars(value.length()) : value.substring(0, 6) + stars(value.length() - 10) + value.substring(value.length() - 4);
+    }
+
+    private String stars(int size) {
+        StringBuilder result = new StringBuilder();
+        for (int i = 0; i < size; i++) result.append('*');
+        return result.toString();
+    }
+
+    private List<TStore> validateStores(List<Integer> storeIds) {
+        List<TStore> stores = new ArrayList<TStore>();
+        Integer currentType = UserExt.getUser().getObjectType();
+        Integer currentObjectId = UserExt.getUser().getObjectId();
+        for (Integer storeId : storeIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList())) {
+            TStore store = storeService.getById(storeId);
+            if (store == null || !Integer.valueOf(1).equals(store.getState())) return null;
+            if ((Integer.valueOf(2).equals(currentType) && !currentObjectId.equals(store.getOperatorId()))
+                    || (Integer.valueOf(3).equals(currentType) && !currentObjectId.equals(store.getId()))) return null;
+            stores.add(store);
+        }
+        return stores;
+    }
+
     /**
      * 删除管理员(逻辑删除)
      * Delete administrator (logical deletion)
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeQuery.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeQuery.java
index ca01165..fca8243 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeQuery.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeQuery.java
@@ -21,4 +21,6 @@
     // 用户ids
     private List<Integer> userIds;
     private Integer insertType;
+    /** 是否包含已退款订单,用于统计支付与退款两条事实流水。 */
+    private Boolean includeRefund;
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeVO.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeVO.java
index 4887fa6..044b1eb 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeVO.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/IncomeVO.java
@@ -29,6 +29,10 @@
     private String payUser;
     private String phone;
     private BigDecimal amount;
+    /** 优惠券抵扣金额(单位:元) */
+    private BigDecimal couponDeductionAmount;
+    /** 退款金额(单位:元) */
+    private BigDecimal refundAmount;
     private Integer incomeType;
     private Integer state;
     // 微信/支付宝流水号
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/RegisterOrderVO.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/RegisterOrderVO.java
index 438a743..f65592d 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/RegisterOrderVO.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/RegisterOrderVO.java
@@ -46,6 +46,8 @@
     private Date insertTime;
     // 支付金额
     private BigDecimal money;
+    /** 用户优惠券领取记录ID */
+    private Long userCouponId;
     // 玩湃币价格/积分
     private Integer playPaiCoin;
     // 该字段用于展示在前端
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
index 3e917ef..149ef87 100644
--- 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
@@ -14,6 +14,7 @@
     private String huiMinName;          // 玩湃惠民卡名称
     private Integer huiMinType;          // 玩湃惠民卡类型(1:年度卡,2:年内卡)
     private BigDecimal salesMoney;      // 售卖金额(精确计算)
+    private Integer paymentType;        // 订单类型(1:微信售卖,2:支付宝售卖,3:赠送)
     
     // 关联信息
     private Integer operatorId;
@@ -29,6 +30,10 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date paymentTime;  // 购买时间[1,8](@ref)
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date refundTime;
+    private Integer refundStatus;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date endTime;      // 有效期
     
@@ -38,4 +43,4 @@
     private Integer useTimes;           // 已用次数
     private Integer status;             // 状态(1:使用中,2:已退款)
     private String orderNumber;             // 支付流水号
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SiteBookingQuery.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SiteBookingQuery.java
index ca11179..0288636 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SiteBookingQuery.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/SiteBookingQuery.java
@@ -19,4 +19,6 @@
     private List<Integer> userIds;
     // 门店ids
     private List<Integer> storeIds;
+    /** 是否包含已取消并退款的预约记录 */
+    private Boolean includeRefund;
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TSiteServiceImpl.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TSiteServiceImpl.java
index 2a3b88e..1fca8ba 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TSiteServiceImpl.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TSiteServiceImpl.java
@@ -44,6 +44,17 @@
         System.out.println("=======date======" + day);
         List<String> strings = new ArrayList<>();
 
+        // 日期为空时无法计算星期和可预约时段,直接返回空结果,避免 LocalDate.parse("") 抛异常。
+        if (StringUtils.isBlank(day)) {
+            return new ArrayList<>();
+        }
+
+        day = day.split(";")[0].trim().split("\\s+")[0];
+        if (StringUtils.isBlank(day)) {
+            return new ArrayList<>();
+        }
+        LocalDate date = LocalDate.parse(day);
+
         List<SiteBooking> siteBookings = iSiteBookingService.list(new QueryWrapper<SiteBooking>().eq("siteId", id).ne("status", 5).eq("nextName", siteName).like("times", day));
 
         if (StringUtils.isBlank(siteName)) {
@@ -86,8 +97,6 @@
 
         TSite site = this.getById(id);
         List<QuerySiteTimes> timeRanges = new ArrayList<>();
-        day = day.split(";")[0].split(" ")[0];
-        LocalDate date = LocalDate.parse(day);
         DayOfWeek dayOfWeek = date.getDayOfWeek();
         // 通过日期 确定周X 查询设置的可以约时间段和金额 封装基础时间段数据
         LambdaQueryWrapper<TSitePrice> tSitePriceLambdaQueryWrapper = new LambdaQueryWrapper<>();
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/transfer/UserDto.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/transfer/UserDto.java
index c20b1c8..24ad57e 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/transfer/UserDto.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/transfer/UserDto.java
@@ -3,6 +3,7 @@
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * 用户传输bean
@@ -30,6 +31,8 @@
 	private Integer version;
 	private String avatar;
 	private String idCard;
+	/** 多门店管理员归属;为空时沿用原有平台/运营商归属逻辑。 */
+	private List<Integer> storeIds;
 
 	public String getIdCard() {
 		return idCard;
@@ -39,6 +42,9 @@
 		this.idCard = idCard;
 	}
 
+	public List<Integer> getStoreIds() { return storeIds; }
+	public void setStoreIds(List<Integer> storeIds) { this.storeIds = storeIds; }
+
 	public Integer getId() {
 		return id;
 	}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelExportUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelExportUtil.java
index 16d5e13..e27d12f 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelExportUtil.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelExportUtil.java
@@ -74,7 +74,8 @@
 			List<String> cellList = dataList.get(y);
 			Row row = sheet.createRow(y);
 			for (int x = 0; x < cellList.size(); x++) {
-				row.createCell(x).setCellValue(cellList.get(x));
+				String header = y > 0 && !dataList.isEmpty() && x < dataList.get(0).size() ? dataList.get(0).get(x) : null;
+				row.createCell(x).setCellValue(maskSensitiveValue(header, cellList.get(x)));
 			}
 		}
 
@@ -88,6 +89,15 @@
 		outStream.close();
 	}
 
+	private static String maskSensitiveValue(String columnName, String value) {
+		if (value == null || columnName == null) return value;
+		String column = columnName.toLowerCase();
+		if (column.contains("身份证") || column.contains("idcard") || column.contains("identity")) return value.length() <= 10 ? stars(value.length()) : value.substring(0, 6) + stars(value.length() - 10) + value.substring(value.length() - 4);
+		if (column.contains("电话") || column.contains("手机") || column.contains("phone") || column.contains("mobile")) return value.length() <= 7 ? stars(value.length()) : value.substring(0, 3) + "****" + value.substring(7);
+		return value;
+	}
+	private static String stars(int count) { StringBuilder result = new StringBuilder(); for (int i = 0; i < count; i++) result.append('*'); return result.toString(); }
+
 	/**
 	 * 复杂杂模板excel导出(合并单元格、设置表格样式等)
 	 * @param request
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelUtil.java
index fd44c75..22e26b5 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelUtil.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/ExcelUtil.java
@@ -32,7 +32,7 @@
 			for (int i = 0; i < values.length; i++) {
 				row = sheet.createRow(i + 1);
 				for (int j = 0; j < values[i].length; j++) {
-					row.createCell(j).setCellValue(values[i][j]);
+					row.createCell(j).setCellValue(maskSensitiveValue(j < title.length ? title[j] : null, values[i][j]));
 				}
 			}
 
@@ -40,6 +40,25 @@
 		return wb;
 	}
 
+	/** Export files are an external disclosure channel and always remain masked. */
+	private static String maskSensitiveValue(String columnName, String value) {
+		if (value == null) return null;
+		String column = columnName == null ? "" : columnName.toLowerCase();
+		if (column.contains("身份证") || column.contains("idcard") || column.contains("identity")) {
+			return value.length() <= 10 ? stars(value.length()) : value.substring(0, 6) + stars(value.length() - 10) + value.substring(value.length() - 4);
+		}
+		if (column.contains("电话") || column.contains("手机") || column.contains("phone") || column.contains("mobile")) {
+			return value.length() <= 7 ? stars(value.length()) : value.substring(0, 3) + "****" + value.substring(7);
+		}
+		return value;
+	}
+
+	private static String stars(int size) {
+		StringBuilder value = new StringBuilder();
+		for (int i = 0; i < size; i++) value.append('*');
+		return value.toString();
+	}
+
 	public static void setResponseHeader(HttpServletResponse response, String fileName) {
 		try {
 			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName));
diff --git a/cloud-server-management/src/main/resources/mapper/MenuMapper.xml b/cloud-server-management/src/main/resources/mapper/MenuMapper.xml
index 9a884ed..3171fb8 100644
--- a/cloud-server-management/src/main/resources/mapper/MenuMapper.xml
+++ b/cloud-server-management/src/main/resources/mapper/MenuMapper.xml
@@ -173,6 +173,7 @@
         )
         ) m3 ON m1.id = m3.id
         where m1.ismenu = 1
+        and m1.status = 1
         order by levels,num asc
     </select>
 
diff --git a/cloud-server-management/src/main/resources/mapper/UserMapper.xml b/cloud-server-management/src/main/resources/mapper/UserMapper.xml
index 2ade598..00b3458 100644
--- a/cloud-server-management/src/main/resources/mapper/UserMapper.xml
+++ b/cloud-server-management/src/main/resources/mapper/UserMapper.xml
@@ -57,18 +57,38 @@
 
 	<update id="setStatus">
 		update sys_user set status = #{status} where id =
-		#{userId}
+													 #{userId}
 	</update>
 
 	<update id="changePwd">
 		update sys_user set password = #{pwd} where id =
-		#{userId}
+													#{userId}
 	</update>
 
 	<update id="setRoles">
 		update sys_user set roleid = #{roleIds} where id =
-		#{userId}
+													  #{userId}
 	</update>
+
+	<delete id="deleteStoreRelations">
+		delete from sys_user_store where userId = #{userId}
+	</delete>
+	<insert id="insertStoreRelations">
+		insert into sys_user_store(id, userId, storeId) values
+		<foreach collection="storeIds" item="storeId" separator=",">
+			<bind name="relationId" value="@com.baomidou.mybatisplus.core.toolkit.IdWorker@getId()"/>
+			(#{relationId}, #{userId}, #{storeId})
+		</foreach>
+	</insert>
+	<select id="getStoreIdsByUserId" resultType="java.lang.Integer">
+		select distinct storeId from (
+										 select storeId from sys_user_store where userId = #{userId}
+										 union all
+										 select objectId as storeId from sys_user where id = #{userId} and objectType = 3 and objectId is not null
+										 union all
+										 select id as storeId from t_store where storeStaffId = #{userId}
+									 ) relation_store
+	</select>
 
 	<select id="getByAccount" resultType="com.dsh.guns.modular.system.model.User">
 		select
@@ -83,7 +103,7 @@
 
 	<select id="getUserListPage" resultType="map" parameterType="com.baomidou.mybatisplus.extension.plugins.pagination.Page">
 		SELECT * FROM (select CASE when d2.simplename is null then d1.simplename else d2.simplename end as parentName,
-		 uu.sex as sexName,
+		uu.sex as sexName,
 		d1.simplename as deptName, uu.status  as statusName,
 		rr.roleName,
 		DATE_FORMAT(uu.createtime, '%Y-%m-%d %H:%i:%s') as createtime1,
@@ -115,10 +135,10 @@
 		</where>
 		order by o.id desc
 	</select>
-    <select id="searchUsers" resultType="com.dsh.guns.modular.system.model.UserListVO">
+	<select id="searchUsers" resultType="com.dsh.guns.modular.system.model.UserListVO">
 		select t1.id,t1.name ,t1.phone ,t1.avatar,t1.birthday,t1.sex,t1.idCard,t1.status,t1.version
-		 ,t2.simplename as deptName from sys_user t1
-		 left join sys_dept t2 on t1.deptid = t2.id
+		,t2.simplename as deptName from sys_user t1
+		left join sys_dept t2 on t1.deptid = t2.id
 		<where>
 			<if test="query.name != null and query.name != ''">
 				and t1.name like CONCAT('%',#{query.name},'%')
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser.html
index ed01d7a..513b36c 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser.html
@@ -96,6 +96,9 @@
                             <#button name="添加" icon="fa-plus" clickFun="TQuestion.openAdd()"/>
                             <#button name="编辑" icon="fa-edit" clickFun="TQuestion.openChange()" space="true"/>
                             <#button name="查看详情" icon="fa-edit" clickFun="TQuestion.openInfo()" space="true"/>
+                            @if(isSuperAdmin){
+                            <#button name="查看敏感信息" icon="fa-eye" clickFun="TQuestion.viewSensitiveData()" space="true"/>
+                            @}
                             <#button name="冻结" icon="fa-check" clickFun="TQuestion.offShelf()" space="true"/>
                             <#button name="解冻" icon="fa-check" clickFun="TQuestion.onShelf()" space="true"/>
                             <#button name="添加学员" icon="fa-edit" clickFun="TQuestion.openAddStudent()" space="true"/>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser_edit.html
index 1292e28..3560e5d 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser_edit.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/appUser/TAppUser_edit.html
@@ -92,7 +92,7 @@
             <div class="form-group" >
                 <label class="col-sm-3 control-label">*联系电话:</label>
                 <div class="col-sm-9" style="display: flex;">
-                    <input style="width: 300px" class="form-control" value="${data.phone}" id="phone"  placeholder="请输入联系电话" type="text">
+                    <input style="width: 300px" class="form-control" value="${data.phone}" id="phone"  placeholder="请输入联系电话" type="text" ${type == 2 ? 'readonly' : ''}>
                 </div>
             </div>
             @if(type == 2){
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/ball/yuyue.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/ball/yuyue.html
index 3ba7085..ce01481 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/ball/yuyue.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/ball/yuyue.html
@@ -106,6 +106,7 @@
                             <#button name="取消预约" icon="fa-edit" clickFun="TStudent.openTStudentDetail4()" space="true"/>
                             <#button name="手动支付" icon="fa-edit" clickFun="TStudent.openTStudentDetail6()" space="true"/>
                             <#button name="查看详情" icon="fa-edit" clickFun="TStudent.openTStudentDetail5()" space="true"/>
+                            <#button name="导出" icon="fa-download" clickFun="TStudent.exportData()" space="true"/>
 <!--                            <button id="exportButton">TTTTTTTTTT</button>-->
                         </div>
                         <#table id="TStudentTable"/>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/operatorIncome.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/operatorIncome.html
index 930fbf8..d12a7b0 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/operatorIncome.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/operatorIncome.html
@@ -37,6 +37,39 @@
         align-items: center;
         justify-content: center;
     }
+    .income-overview {
+        display: grid;
+        grid-template-columns: repeat(4, minmax(180px, 1fr));
+        gap: 16px;
+        width: 100%;
+        max-width: 1280px;
+        margin: 18px 0;
+        text-align: left;
+    }
+    .income-card {
+        min-height: 82px;
+        padding: 16px 18px;
+        border: 1px solid #e4e7ed;
+        border-radius: 6px;
+        background: #fff;
+        color: #606266;
+        font-size: 14px;
+        box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
+    }
+    .income-card strong {
+        display: block;
+        margin-top: 8px;
+        color: #303133;
+        font-size: 22px;
+        font-weight: 600;
+    }
+    .income-card.total-card { border-top: 3px solid #1ab394; }
+    .income-card.net-card { border-top: 3px solid #409eff; }
+    .income-card.coupon-card { border-top: 3px solid #e6a23c; }
+    .income-card.refund-card { border-top: 3px solid #f56c6c; }
+    \@media (max-width: 992px) {
+        .income-overview { grid-template-columns: repeat(2, minmax(180px, 1fr)); }
+    }
 </style>
 <div class="ibox float-e-margins">
     <div class="ibox-content">
@@ -78,16 +111,18 @@
                             <div class="form-group">
                                 <div class="col-sm-10">
                                     <h2>营收数据</h2>
-                                    </br>
-                                        <div id = "money1" style="width: 1500px" >
-                                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span id="totalIncome">总营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                            <span id="yearIncome">本年度营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                            <span id="monthIncome">本月度营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                            <span id="weekIncome">本周营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                            <span id="todayIncome">本日营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                            </br>
-                                            </br>
+                                    <div id="money1">
+                                        <div class="income-overview">
+                                            <div class="income-card total-card">总营收金额<strong id="totalIncome">0</strong></div>
+                                            <div class="income-card net-card">净收入金额<strong id="netIncomeAmount">0</strong></div>
+                                            <div class="income-card coupon-card">优惠券抵扣金额<strong id="couponDeductionAmount">0</strong></div>
+                                            <div class="income-card refund-card">退款金额<strong id="refundAmount">0</strong></div>
                                         </div>
+                                        <span id="yearIncome" style="display:none"></span>
+                                        <span id="monthIncome" style="display:none"></span>
+                                        <span id="weekIncome" style="display:none"></span>
+                                        <span id="todayIncome" style="display:none"></span>
+                                    </div>
                                     <div id="income" style="width: 1280px;height:500px;"></div>
                                 </div>
                                 <div class="col-sm-10">
@@ -340,8 +375,14 @@
             var t3 = document.getElementById("monthIncome");
             var t4 = document.getElementById("weekIncome");
             var t5 = document.getElementById("todayIncome");
-            t1.innerText = "总营收:"+list[0]+"         ";
-            t2.innerText = "年度营收:"+list[1]+"         ";
+            var netIncomeAmount = document.getElementById("netIncomeAmount");
+            var couponDeductionAmount = document.getElementById("couponDeductionAmount");
+            var refundAmount = document.getElementById("refundAmount");
+            t1.innerText = list[0] || 0;
+            t2.innerText = "年度应收:"+list[1]+"         ";
+            netIncomeAmount.innerText = resp.netIncomeAmount || 0;
+            couponDeductionAmount.innerText = resp.couponDeductionAmount || 0;
+            refundAmount.innerText = resp.refundAmount || 0;
             t3.innerText = "月度营收:"+list[2]+"         ";
             t4.innerText = "周度营收:"+list[3]+"         ";
             t5.innerText = "日度营收:"+list[4]+"         ";
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/platformIncome.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/platformIncome.html
index 4ba8bf4..af931d6 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/platformIncome.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/dataStatistics/platformIncome.html
@@ -37,6 +37,57 @@
         align-items: center;
         justify-content: center;
     }
+    .income-overview {
+        display: grid;
+        grid-template-columns: repeat(4, minmax(180px, 1fr));
+        gap: 16px;
+        width: 100%;
+        max-width: 1280px;
+        margin: 18px 0 14px;
+        text-align: left;
+    }
+    .income-card {
+        min-height: 82px;
+        padding: 16px 18px;
+        border: 1px solid #e4e7ed;
+        border-radius: 6px;
+        background: #fff;
+        color: #606266;
+        font-size: 14px;
+        box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
+    }
+    .income-card strong {
+        display: block;
+        margin-top: 8px;
+        color: #303133;
+        font-size: 22px;
+        font-weight: 600;
+    }
+    .income-card.total-card { border-top: 3px solid #1ab394; }
+    .income-card.net-card { border-top: 3px solid #409eff; }
+    .income-card.coupon-card { border-top: 3px solid #e6a23c; }
+    .income-card.refund-card { border-top: 3px solid #f56c6c; }
+    .income-period-grid {
+        display: grid;
+        grid-template-columns: repeat(2, minmax(360px, 1fr));
+        gap: 10px 16px;
+        width: 100%;
+        max-width: 1280px;
+        margin-bottom: 18px;
+        text-align: left;
+    }
+    .income-period-item {
+        min-height: 38px;
+        padding: 9px 12px;
+        border-left: 3px solid #1ab394;
+        background: #f8fafc;
+        color: #606266;
+        line-height: 20px;
+    }
+    \@media (max-width: 992px) {
+        .income-overview { grid-template-columns: repeat(2, minmax(180px, 1fr)); }
+        .income-period-grid { grid-template-columns: 1fr; }
+    }
 </style>
 <div class="ibox float-e-margins">
     <div class="ibox-content">
@@ -66,15 +117,23 @@
                             <div class="form-group">
                                 <div class="col-sm-10">
                                     <h2>营收数据</h2>
-                                    </br>
-                                    <div id = "money1" style="width: 1500px" >
-                                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span id="totalIncome">总营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                        <span id="yearIncome">本年度营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                        <span id="monthIncome">本月度营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                        <span id="weekIncome">本周营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                        <span id="todayIncome">本日营收:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-                                        </br>
-                                        </br>
+                                    <div id="money1">
+                                        <div class="income-overview">
+                                            <div class="income-card total-card">总营收金额<strong id="totalIncome">0</strong></div>
+                                            <div class="income-card net-card">净收入金额<strong id="netIncomeAmount">0</strong></div>
+                                            <div class="income-card coupon-card">优惠券抵扣金额<strong id="couponDeductionAmount">0</strong></div>
+                                            <div class="income-card refund-card">退款金额<strong id="refundAmount">0</strong></div>
+                                        </div>
+                                        <div class="income-period-grid">
+                                            <div id="yearIncomeStatistics" class="income-period-item"></div>
+                                            <div id="monthIncomeStatistics" class="income-period-item"></div>
+                                            <div id="weekIncomeStatistics" class="income-period-item"></div>
+                                            <div id="dayIncomeStatistics" class="income-period-item"></div>
+                                        </div>
+                                        <span id="yearIncome" style="display:none"></span>
+                                        <span id="monthIncome" style="display:none"></span>
+                                        <span id="weekIncome" style="display:none"></span>
+                                        <span id="todayIncome" style="display:none"></span>
                                     </div>
                                     <div id="main" style="width: 1280px;height:500px;"></div>
                                 </div>
@@ -305,6 +364,14 @@
         });
         ajax2.start()
     }
+
+    function renderIncomeStatistics(elementId, periodName, statistics) {
+        document.getElementById(elementId).innerText = periodName + "统计:总营收金额 "
+            + statistics.totalIncomeAmount + ",净收入金额 " + statistics.netIncomeAmount
+            + ",优惠券抵扣金额 " + statistics.couponDeductionAmount + ",退款金额 "
+            + statistics.refundAmount;
+    }
+
     $(function(){
         getContent(1);
         getContent1(1);
@@ -323,11 +390,21 @@
             var t3 = document.getElementById("monthIncome");
             var t4 = document.getElementById("weekIncome");
             var t5 = document.getElementById("todayIncome");
-            t1.innerText = "总营收:"+list[0]+"         ";
+            var netIncomeAmount = document.getElementById("netIncomeAmount");
+            var couponDeductionAmount = document.getElementById("couponDeductionAmount");
+            var refundAmount = document.getElementById("refundAmount");
+            t1.innerText = list[0] || 0;
             t2.innerText = "年度营收:"+list[1]+"         ";
             t3.innerText = "月度营收:"+list[2]+"         ";
             t4.innerText = "周度营收:"+list[3]+"         ";
             t5.innerText = "日度营收:"+list[4]+"         ";
+            netIncomeAmount.innerText = resp.incomeStatistics.netIncomeAmount || 0;
+            couponDeductionAmount.innerText = resp.incomeStatistics.couponDeductionAmount || 0;
+            refundAmount.innerText = resp.incomeStatistics.refundAmount || 0;
+            renderIncomeStatistics("yearIncomeStatistics", "年度", resp.yearIncomeStatistics[resp.yearIncomeStatistics.length - 1]);
+            renderIncomeStatistics("monthIncomeStatistics", "月度", resp.monthIncomeStatistics[new Date().getMonth()]);
+            renderIncomeStatistics("weekIncomeStatistics", "周度", resp.weekIncomeStatistics[resp.weekIncomeStatistics.length - 1]);
+            renderIncomeStatistics("dayIncomeStatistics", "日度", resp.dayIncomeStatistics[resp.dayIncomeStatistics.length - 1]);
             var year =  resp.yearIncome;
             var month =  resp.monthIncome;
             var week =  resp.weekIncome;
@@ -390,7 +467,7 @@
                         type: 'line',
                         stack: 'Total',
                         data: [
-                            week[0][0], week[0][1], week[0][2], week[0][3], week[0][4]
+                            week[0][0], week[0][1], week[0][2], week[0][3]
                         ]
                     },
                     {
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition.html
index eba49ba..35067bf 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition.html
@@ -4,7 +4,7 @@
         <div class="ibox float-e-margins">
 
             <div class="ibox-title">
-                <h5>赛事管理</h5>
+                <h5>活动管理</h5>
             </div>
             <input hidden id="type" value="${type}">
             <div class="ibox-content">
@@ -43,7 +43,7 @@
                                 <#NameCon id="shopName" name="门店名称" />
                             </div>
                             <div class="col-sm-3">
-                                <#NameCon id="eventName" name="赛事名称" />
+                                <#NameCon id="eventName" name="活动名称" />
                             </div>
                             <div class="col-sm-3">
                                 <#TimeCon id="createTime" name="时间" isTime="false"/>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html
index 19f0de5..64d959e 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_add.html
@@ -51,10 +51,10 @@
 
             @if(type==1){
             <div class="form-group">
-                <label class="col-sm-3 control-label">*赛事类型:</label>
+                <label class="col-sm-3 control-label">*活动类型:</label>
                 <div class="col-sm-9">
-                    <input type="radio" name="type" value="1" onclick="updateType(1)" checked > 平台赛事
-                    <input type="radio" name="type" value="2" onclick="updateType(2)" id="radio1" > 运营赛事
+                    <input type="radio" name="type" value="1" onclick="updateType(1)" checked > 平台活动
+                    <input type="radio" name="type" value="2" onclick="updateType(2)" id="radio1" > 运营活动
                 </div>
             </div>
             <div id="yys" hidden>
@@ -152,7 +152,7 @@
                 </div>
             </div>
             @}
-        <#input id="name" name="赛事名称" type="text"/>
+        <#input id="name" name="活动名称" type="text"/>
         <#input id="startTime" name="开始时间" type="text"/>
         <#input id="endTime" name="结束时间" type="text"/>
         <#input id="registerEndTime" name="截止报名时间" type="text"/>
@@ -226,16 +226,16 @@
             </div>
 
                 <div class="form-group">
-                    <label class="col-sm-3 control-label">赛事简介:</label>
+                    <label class="col-sm-3 control-label">活动简介:</label>
                     <div class="col-sm-9">
                         <textarea  id="introduction" style="height: 203px; width: 506px;"></textarea>
                     </div>
                 </div>
 
-                <#avatar id="coverDrawing" name="赛事封面(推荐像素:210*280px)" avatarImg=""/>
+                <#avatar id="coverDrawing" name="活动封面(推荐像素:210*280px)" avatarImg=""/>
             <div class="row" id="app1">
                 <div class="form-group">
-                    <label class="col-sm-3 control-label head-scu-label">*赛事活动图片(请上传不超过五张图片): </label>
+                    <label class="col-sm-3 control-label head-scu-label">*活动图片(请上传不超过五张图片): </label>
                     <div class="col-sm-2" style="width: 100%;margin-left: 11%;margin-top: 1%">
                         <el-upload
                                 :limit="5"
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html
index dfcb68d..94aef06 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetition/TCompetition_edit.html
@@ -91,11 +91,10 @@
                     <input id="storeIds" type="hidden" value="${storeIds}">
                 </div>
             </div>
-            <#input id="name" name="赛事名称" type="text" value="${item.name}"/>
+            <#input id="name" name="活动名称" type="text" value="${item.name}"/>
             <#input id="startTime" name="开始时间" type="text" value="${startTime}"/>
             <#input id="endTime" name="结束时间" type="text" value="${endTime}"/>
             <#input id="registerEndTime" name="截止报名时间" type="text"  value="${registerEndTime}"/>
-            @if(type==2){
             <div class="form-group">
                 <label class="col-sm-3 control-label">报名条件:</label>
                 <div class="col-sm-9">
@@ -141,8 +140,6 @@
                     <input class="form-control"  style="width: 200px;" type="text" id="classPrice" value="${item.classPrice}">
                 </div>
             </div>
-            @}
-
             <div class="form-group">
                 <label class="col-sm-3 control-label">参加地点:</label>
                 <div class="col-sm-9">
@@ -168,13 +165,13 @@
             </div>
 
             <div class="form-group">
-                <label class="col-sm-3 control-label">赛事简介:</label>
+                <label class="col-sm-3 control-label">活动简介:</label>
                 <div class="col-sm-9">
                     <textarea  id="introduction" style="height: 203px; width: 506px;">${item.introduction}</textarea>
                 </div>
             </div>
 
-            <#avatar id="coverDrawing" name="赛事封面(推荐像素:210*280px):" avatarImg="${item.coverDrawing}" />
+            <#avatar id="coverDrawing" name="活动封面(推荐像素:210*280px):" avatarImg="${item.coverDrawing}" />
             <div class="row" id="app1">
                 <div class="form-group">
                     <label class="col-sm-3 control-label head-scu-label">*实景图片(请上传不超过五张图片): </label>
@@ -319,15 +316,15 @@
             }
         }
 
-        if($("#q1").val()>0 && $("#type").val()==2){
+        if($("#q1").val()>0){
             $("#payType1").show();
             $("input[id='t1']").attr("checked", "checked")
         }
-        if($("#q2").val()>0 && $("#type").val()==2){
+        if($("#q2").val()>0){
             $("#payType2").show();
             $("input[id='t2']").attr("checked", "checked")
         }
-        if($("#q3").val()>0 && $("#type").val()==2){
+        if($("#q3").val()>0){
             $("#payType3").show();
             $("input[id='t3']").attr("checked", "checked")
         }
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition.html
index b9dd845..af42ee6 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition.html
@@ -4,7 +4,7 @@
         <div class="ibox float-e-margins">
 
             <div class="ibox-title">
-                <h5>赛事审核</h5>
+                <h5>活动审核</h5>
             </div>
 
             <div class="ibox-content">
@@ -41,7 +41,7 @@
                                 <#NameCon id="shopName" name="门店名称" />
                             </div>
                             <div class="col-sm-3">
-                                <#NameCon id="eventName" name="赛事名称" />
+                                <#NameCon id="eventName" name="活动名称" />
                             </div>
                             <div class="col-sm-3">
                                 <#SelectCon id="state" name="状态" >
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_add.html
index 1adda3f..be03780 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_add.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_add.html
@@ -33,7 +33,7 @@
                     </select>
                 </div>
             </div>
-        <#input id="name" name="赛事名称" type="text"/>
+        <#input id="name" name="活动名称" type="text"/>
         <#input id="startTime" name="开始时间" type="text"/>
         <#input id="endTime" name="结束时间" type="text"/>
         <#input id="registerEndTime" name="截止报名时间" type="text"/>
@@ -107,14 +107,14 @@
             </div>
 
                 <div class="form-group">
-                    <label class="col-sm-3 control-label">赛事简介:</label>
+                    <label class="col-sm-3 control-label">活动简介:</label>
                     <div class="col-sm-9">
                         <textarea  id="introduction" style="height: 203px; width: 506px;"></textarea>
                     </div>
                 </div>
 
-                <#avatar id="coverDrawing" name="赛事封面(推荐像素:210*280px):" />
-                <#avatar id="imgs" name="赛事图片(推荐像素:780*440px):" />
+                <#avatar id="coverDrawing" name="活动封面(推荐像素:210*280px):" />
+                <#avatar id="imgs" name="活动图片(推荐像素:780*440px):" />
                 <#avatar id="registrationNotes" name="报名须知(推荐像素:宽780px):" />
 
         </div>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_edit.html
index d7566ff..817719b 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_edit.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tCompetitionAudit/TCompetition_edit.html
@@ -48,7 +48,7 @@
                     </select>
                 </div>
             </div>
-            <#input id="name" name="赛事名称" type="text" value="${item.name}" readonly="true"/>
+            <#input id="name" name="活动名称" type="text" value="${item.name}" readonly="true"/>
             <#input id="startTime" name="开始时间" type="text" value="${item.startTime}" readonly="true"/>
             <#input id="endTime" name="结束时间" type="text" value="${item.endTime}" readonly="true"/>
             <#input id="registerEndTime" name="截止报名时间" type="text"  value="${item.registerEndTime}" readonly="true"/>
@@ -125,15 +125,15 @@
             </div>
 
             <div class="form-group">
-                <label class="col-sm-3 control-label">赛事简介:</label>
+                <label class="col-sm-3 control-label">活动简介:</label>
                 <div class="col-sm-9">
                     <textarea  id="introduction" style="height: 203px; width: 506px;" readonly>${item.introduction}</textarea>
                 </div>
             </div>
 
-            <#avatar id="coverDrawing" name="赛事封面(推荐像素:210*280px):" avatarImg="${item.coverDrawing}" />
+            <#avatar id="coverDrawing" name="活动封面(推荐像素:210*280px):" avatarImg="${item.coverDrawing}" />
             <div class="form-group">
-                <label class="col-sm-3 control-label head-scu-label">赛事图片(推荐像素:780*440px):</label>
+                <label class="col-sm-3 control-label head-scu-label">活动图片(推荐像素:780*440px):</label>
                 <div class="col-sm-4">
                     <div id="imgsPreId">
                         @for(i in imgs){
@@ -267,7 +267,7 @@
         let audit = document.querySelector('input[name="auditType"]:checked').value;
         var state = $("#state").val();
         if(state==3){
-            Feng.error("当前赛事状态不能再审核!")
+            Feng.error("当前活动状态不能再审核!")
             return ;
         }
         let text = $("#text").val()
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_one.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_one.html
index 129f9ea..7eeeb80 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_one.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_one.html
@@ -41,7 +41,7 @@
 </style>
 <div class="ibox float-e-margins">
     <div class="ibox-content">
-        <input id="s1" value="${item.redemptionMethod}" hidden>
+        <input id="s1" value="${item.exchangeMethod}" hidden>
 
         <div class="form-horizontal" id="carInfoForm">
             <div id="b1">
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_payOne.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_payOne.html
index 1fc916d..8b16244 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_payOne.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_payOne.html
@@ -3,6 +3,24 @@
     <div class="col-sm-12">
         <div class="ibox float-e-margins">
             <input id="id" value="${id}" hidden="hidden">
+            <!-- 门票管理购买详情的入园方式弹窗内容;选项值与后端 goType 保持一致。 -->
+            <script type="text/html" id="ticketEntryMethodTemplate">
+                <div class="form-horizontal">
+                    <div class="col-sm-11">
+                        <div class="col-sm-11">
+                            <div class="form-group">
+                                <label class="col-sm-3 control-label">请选择:</label>
+                                <div class="col-sm-9" style="margin-top: 5px;">
+                                    <input type="radio" id="areaType1" value="1" name="areaType" checked>
+                                    <label for="areaType1">手环</label>
+                                    <input type="radio" id="areaType2" value="2" name="areaType">
+                                    <label for="areaType2">门票核销</label>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </script>
             <div class="ibox-content">
                 <div class="row row-lg">
                     <div class="col-sm-12">
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html
index 20afd1f..920550c 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html
@@ -62,6 +62,10 @@
                     </select>
                 </div>
             </div>
+            <div class="form-group">
+                <label class="col-sm-3 control-label">订单类型:</label>
+                <div class="col-sm-9" style="padding-top: 7px;">赠送</div>
+            </div>
 
             @if(role==1){
             <div class="form-group">
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html
index 921cb91..38909fe 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html
@@ -129,8 +129,6 @@
                     <textarea placeholder= "请输入门店介绍" id="introduce" style="width: 617px; height: 180px;"></textarea>
                 </div>
             </div>
-        <#input id="userName" name="*店长姓名" placeholder= "请输入店长姓名" type="text"/>
-        <#input id="userPhone" name="*店长手机号" placeholder= "请输入店长手机号" type="text"/>
         <#avatar id="img" name="*门店封面(推荐像素722*360px)" avatarImg="" />
             <div class="row" id="app1">
                 <div class="col-sm-6" style="width: 100%;margin-left: 103px;">
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_edit.html
index a654fe2..268b481 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_edit.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_edit.html
@@ -108,8 +108,6 @@
                     <textarea id="introduce" style="width: 617px; height: 180px;">${item.introduce}</textarea>
                 </div>
             </div>
-            <#input id="userName" name="管理员姓名" type="text" value="${city.name}"/>
-            <#input id="userPhone" name="管理员手机号" type="text" value="${city.account}"/>
             <#avatar id="img" name="门店封面(推荐像素722*360px)" avatarImg="${item.coverDrawing}"/>
             <div class="row" id="app1">
                 <div class="col-sm-6" style="width: 100%;margin-left: 103px;">
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user.html
index dc53d53..151674a 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user.html
@@ -58,6 +58,9 @@
 							@if(shiro.hasPermission("/mgr/delete")){
 							<#button name="查看详情" icon="fa-remove" clickFun="MgrUser.openChangeUser1()" space="true"/>
 							@}
+							@if(isSuperAdmin){
+							<#button name="查看敏感信息" icon="fa-eye" clickFun="MgrUser.viewSensitiveData()" space="true"/>
+							@}
 							@if(shiro.hasPermission("/mgr/freeze")){
 							<#button name="冻结" icon="fa-warning" clickFun="MgrUser.freezeAccount()" space="true"/>
 							@}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_add.html
index f7997c3..e2c9d73 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_add.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_add.html
@@ -30,6 +30,17 @@
                     @}
                 </#select>
             @}
+                <div class="form-group">
+                    <label class="col-sm-3 control-label">归属门店</label>
+                    <div class="col-sm-9">
+                        <select class="form-control" id="storeIds" name="storeIds" multiple="multiple">
+                            @for(store in stores){
+                            <option value="${store.id}">${store.name}</option>
+                            @}
+                        </select>
+                        <span class="help-block">可多选:Windows/Linux 按住 Ctrl 键逐项点击;Mac 按住 ⌘ 键逐项点击。再次点击已选项可取消选择。</span>
+                    </div>
+                </div>
 
             </div>
         </div>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_edit.html
index 16cbe7d..12ad591 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_edit.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/user/user_edit.html
@@ -5,6 +5,7 @@
 			<input type="hidden" id="id" value="${user.id}">
 			<input type="hidden" id="sexValue" value="${user.sex}">
 			<input type="hidden" id="roleid_" value="${user.roleid}">
+			<input type="hidden" id="selectedStoreIds" value="${selectedStoreIds}">
 			<div class="row">
 				<div class="col-sm-6">
 					<div id="driverInfoContent">
@@ -22,13 +23,24 @@
 					<option value="${l.id}" ${l.id == user.roleid ? 'selected=selected' : ''}>${l.name}</option>
 					@}
 				</#select>
-					@if(role == 1){
+				@if(role == 1){
 					<#select id="deptid" name="角色" underline="true" >
 					@for(l in depts){
 					    <option value="${l.id}" ${l.id == user.deptid ? 'selected=selected' : ''}>${l.fullname}</option>
 					@}
 					</#select>
 				@}
+					<div class="form-group">
+						<label class="col-sm-3 control-label">归属门店</label>
+						<div class="col-sm-9">
+							<select class="form-control" id="storeIds" name="storeIds" multiple="multiple">
+								@for(store in stores){
+								<option value="${store.id}">${store.name}</option>
+								@}
+							</select>
+							<span class="help-block">可多选:Windows/Linux 按住 Ctrl 键逐项点击;Mac 按住 ⌘ 键逐项点击。</span>
+						</div>
+					</div>
 			</div>
 		</div>
 	</div>
@@ -60,5 +72,12 @@
 	laydate.render({
 		elem: '#birthday'
 	});
+	$(function () {
+		// 门店随编辑页一次性渲染,避免异步请求失败时多选框没有任何回显。
+		var selectedStoreIds = ($("#selectedStoreIds").val() || "").split(",");
+		$("#storeIds option").each(function () {
+			this.selected = $.inArray(String(this.value), selectedStoreIds) !== -1;
+		});
+	});
 </script>
 @}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/worldCup/worldCup.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/worldCup/worldCup.html
index 0998b88..654deb0 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/worldCup/worldCup.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/worldCup/worldCup.html
@@ -3,7 +3,7 @@
     <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">
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/appUser/tAppUser.js b/cloud-server-management/src/main/webapp/static/modular/system/appUser/tAppUser.js
index 316d3b2..ec111f3 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/appUser/tAppUser.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/appUser/tAppUser.js
@@ -35,7 +35,7 @@
         {title: '注册时间', field: 'insertTime', visible: true, align: 'center', valign: 'middle'},
         {title: '状态', field: 'state', visible: true, align: 'center', valign: 'middle',
             formatter:function (data) {
-                return {1:"正常",2:"冻结",3:"已注销"}[data]
+                return {1:"正常",2:"冻结",3:"注销"}[data]
             }}
     ];
 };
@@ -147,6 +147,32 @@
             this.layerIndex = index;
         }
     }
+};
+
+/** Only rendered for admin. The server independently checks admin and audits every successful view. */
+TQuestion.viewSensitiveData = function () {
+    var selected = $('#' + this.id).bootstrapTable('getSelections');
+    if (selected.length > 1) {
+        Feng.info("只能选择一个用户进行查看!");
+        return;
+    }
+    if (!this.check()) return;
+    layer.confirm('查看完整手机号和身份证号将记录审计日志,是否继续?', {icon: 3, title: '敏感信息查看'}, function (index) {
+        $.ajax({
+            url: Feng.ctxPath + '/system/sensitive/app-user/' + TQuestion.seItem.id,
+            type: 'GET',
+            success: function (data) {
+                if (!data) { Feng.info('未查询到用户信息'); return; }
+                var html = '<div style="padding:20px;line-height:28px">'
+                    + '<div>姓名:' + (data.name || '') + '</div>'
+                    + '<div>手机号:' + (data.phone || '') + '</div>'
+                    + '<div>身份证号:' + (data.idCard || '') + '</div></div>';
+                layer.open({type: 1, title: '用户敏感信息(已记录审计日志)', area: ['420px', '260px'], content: html});
+            },
+            error: function () { Feng.error('无权查看敏感信息或查询失败'); }
+        });
+        layer.close(index);
+    });
 };
 /**
  * 查看学员详情
@@ -292,6 +318,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选内容?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeState",
             type: "POST",
@@ -305,6 +332,7 @@
                 var errorMessage = xhr.responseText ? xhr.responseText : "删除失败!";
                 Feng.error(errorMessage);
             }
+        });
         });
     }
 };
@@ -375,7 +403,6 @@
         Feng.info("请选择性别")
         return;
     }
-
     $.ajax({
         url: Feng.ctxPath + "/appUser/addAppUser" ,
         type: "POST",
@@ -542,7 +569,6 @@
         Feng.info("请选择销售人员")
         return;
     }
-
     $.ajax({
         url: Feng.ctxPath + "/appUser/addAppUser" ,
         type: "POST",
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/ball/ball.js b/cloud-server-management/src/main/webapp/static/modular/system/ball/ball.js
index dbb608e..4d115ab 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/ball/ball.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/ball/ball.js
@@ -245,14 +245,18 @@
  */
 TStudent.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tStudent/delete", function (data) {
             Feng.success("删除成功!");
             TStudent.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tStudentId",this.seItem.id);
+        ajax.set("tStudentId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue.js b/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue.js
index df3cb6f..573a880 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue.js
@@ -183,8 +183,9 @@
 TStudent.openTStudentDetail1 = function () {
     if (this.check()) {
 
-        if (TStudent.seItem.status!=1){
-            Feng.error("请选择待核销的数据")
+        // 运营人员可人工确认已过期但实际已入场的门票;服务端会将其置为“已完成”。
+        if (TStudent.seItem.status != 1 && TStudent.seItem.status != 4){
+            Feng.error("请选择待核销或已过期的数据")
             return
         }
         var index = layer.open({
@@ -286,14 +287,18 @@
  */
 TStudent.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tStudent/delete", function (data) {
             Feng.success("删除成功!");
             TStudent.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tStudentId",this.seItem.id);
+        ajax.set("tStudentId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该记录?", operation);
     }
 };
 
@@ -301,16 +306,27 @@
  * 查询列表
  */
 TStudent.search = function () {
-    var queryData = {};
-    queryData['provinceCode'] = $("#pCode").val();
-    queryData['cityCode'] = $("#cCode").val();
-    queryData['store'] = $("#store").val();
-    queryData['peopleName'] = $("#peopleName").val();
-    queryData['phone'] = $("#phone").val();
-    queryData['date'] = $("#date").val();
-    queryData['payMethod'] = $("#payMethod").val();
-    queryData['state'] = $("#state").val();
-    TStudent.table.refresh({query: queryData});
+    TStudent.table.refresh({query: TStudent.getQueryData()});
+};
+
+/** 获取当前筛选条件,列表查询与导出保持完全一致。 */
+TStudent.getQueryData = function () {
+    return {
+        provinceCode: $("#pCode").val(),
+        cityCode: $("#cCode").val(),
+        store: $("#store").val(),
+        peopleName: $("#peopleName").val(),
+        phone: $("#phone").val(),
+        date: $("#date").val(),
+        payMethod: $("#payMethod").val(),
+        state: $("#state").val()
+    };
+};
+
+/** 按当前条件下载全部预约记录。 */
+TStudent.exportData = function () {
+    var queryString = $.param(TStudent.getQueryData());
+    window.location.href = Feng.ctxPath + "/ball/yuyueexport?" + queryString;
 };
 /**
  * 重置
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue_info.js b/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue_info.js
index c361ad4..142ed37 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue_info.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/ball/yuyue_info.js
@@ -46,6 +46,13 @@
 
 CoursePackageInfo.addTime = function (a) {
     console.log("==========="+a)
+
+    var day = $.trim($('#time').val());
+    if (!day) {
+        $('#timeSlotTable').hide();
+        $('#noDataTip').show().text('请先选择预约日期');
+        return;
+    }
     
     // 获取入场方式
     var targetAudience = $('input[name="targetAudience"]:checked').val() || 1;
@@ -165,7 +172,7 @@
     });
     
     ajax.set("id", $('#siteId').val());
-    ajax.set("day", $('#time').val());
+    ajax.set("day", day);
     ajax.set("targetAudience", targetAudience);
 
     console.log("类型")
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/benefits/TBenefits.js b/cloud-server-management/src/main/webapp/static/modular/system/benefits/TBenefits.js
index 40ad86d..4ffe12f 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/benefits/TBenefits.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/benefits/TBenefits.js
@@ -223,6 +223,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选内容?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeState",
             type: "POST",
@@ -237,6 +238,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos.js b/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos.js
index ce90287..61a0f05 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos.js
@@ -234,6 +234,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选视频?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeCourseState",
             type: "POST",
@@ -248,6 +249,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_add.js b/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_add.js
index 10414df..ccfecae 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_add.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_add.js
@@ -240,6 +240,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选视频?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeCourseState",
             type: "POST",
@@ -254,6 +255,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_edit.js b/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_edit.js
index 0801cf0..d304aec 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_edit.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/benefits/tBenefitsVideos_edit.js
@@ -227,6 +227,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选视频?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeCourseState",
             type: "POST",
@@ -241,6 +242,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment.js b/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment.js
index 268dddd..0e48006 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment.js
@@ -205,6 +205,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选预约?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeState",
             type: "POST",
@@ -219,6 +220,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment_edit.js b/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment_edit.js
index 5a8d5ed..f7d68dc 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment_edit.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/bodySideAppointment/tBodySideAppointment_edit.js
@@ -266,6 +266,7 @@
             data1.ids.push(id);
         });
         data1.state = 3;
+        Feng.confirm("确认删除所选预约?", function () {
         $.ajax({
             url: Feng.ctxPath + "/benefits/changeCourseState",
             type: "POST",
@@ -280,6 +281,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 TQuestion.close = function() {
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/driverActivity/driverActivity.js b/cloud-server-management/src/main/webapp/static/modular/system/driverActivity/driverActivity.js
index 9734455..324e524 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/driverActivity/driverActivity.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/driverActivity/driverActivity.js
@@ -192,14 +192,18 @@
  */
 DriverActivity.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/driverActivity/delete", function (data) {
              Feng.success("删除成功!");
             DriverActivity.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("driverActivityId",this.seItem.id);
+        ajax.set("driverActivityId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该活动?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/driverActivityHistory/driverActivityHistory.js b/cloud-server-management/src/main/webapp/static/modular/system/driverActivityHistory/driverActivityHistory.js
index c109c06..7898e1c 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/driverActivityHistory/driverActivityHistory.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/driverActivityHistory/driverActivityHistory.js
@@ -93,14 +93,18 @@
  */
 DriverActivityHistory.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/driverActivityHistory/delete", function (data) {
              Feng.success("删除成功!");
             DriverActivityHistory.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("driverActivityHistoryId",this.seItem.id);
+        ajax.set("driverActivityHistoryId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该活动记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/sysCouponRecord/sysCouponRecord.js b/cloud-server-management/src/main/webapp/static/modular/system/sysCouponRecord/sysCouponRecord.js
index 5174832..ba1fa79 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/sysCouponRecord/sysCouponRecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/sysCouponRecord/sysCouponRecord.js
@@ -206,14 +206,18 @@
  */
 SysCouponRecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/sysCouponRecord/delete", function (data) {
              Feng.success("删除成功!");
             SysCouponRecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("sysCouponRecordId",this.seItem.id);
+        ajax.set("sysCouponRecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该优惠券记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/sysRedPacketRecord/sysRedPacketRecord.js b/cloud-server-management/src/main/webapp/static/modular/system/sysRedPacketRecord/sysRedPacketRecord.js
index c53eece..cd468f5 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/sysRedPacketRecord/sysRedPacketRecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/sysRedPacketRecord/sysRedPacketRecord.js
@@ -110,14 +110,18 @@
  */
 SysRedPacketRecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/sysRedPacketRecord/delete", function (data) {
              Feng.success("删除成功!");
             SysRedPacketRecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("sysRedPacketRecordId",this.seItem.id);
+        ajax.set("sysRedPacketRecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该红包记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tAgreement/tAgreement.js b/cloud-server-management/src/main/webapp/static/modular/system/tAgreement/tAgreement.js
index 0e31d1b..924e59f 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tAgreement/tAgreement.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tAgreement/tAgreement.js
@@ -77,14 +77,18 @@
  */
 TAgreement.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tAgreement/delete", function (data) {
              Feng.success("删除成功!");
             TAgreement.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tAgreementId",this.seItem.id);
+        ajax.set("tAgreementId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该协议?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tAuditRecord/tAuditRecord.js b/cloud-server-management/src/main/webapp/static/modular/system/tAuditRecord/tAuditRecord.js
index a6de1c8..3775e2b 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tAuditRecord/tAuditRecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tAuditRecord/tAuditRecord.js
@@ -76,14 +76,18 @@
  */
 TAuditRecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tAuditRecord/delete", function (data) {
             Feng.success("删除成功!");
             TAuditRecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tAuditRecordId",this.seItem.id);
+        ajax.set("tAuditRecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该审核记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition.js b/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition.js
index 059ce55..3564407 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition.js
@@ -22,7 +22,7 @@
         {title: '所在市', field: 'city', visible: type==2?false:true, align: 'center', valign: 'middle'},
         {title: '举办门店', field: 'storeName', visible: true, align: 'center', valign: 'middle',width:'8%',
         },
-        {title:  '赛事名称', field: 'name', visible: true, align: 'center', valign: 'middle',width:'8%',
+        {title:  '活动名称', field: 'name', visible: true, align: 'center', valign: 'middle',width:'8%',
         },
         {title: '开始时间', field: 'startTime', visible: true, align: 'center', valign: 'middle',width:'8%',
         },
@@ -158,9 +158,9 @@
  */
 TCompetition.delete = function () {
     if (this.check()) {
-        var nickname = TCompetition.seItem.carLicensePlate;
+        var nickname = TCompetition.seItem.name;
         if (nickname == "" || nickname == null || nickname == undefined){
-                nickname = "该赛事";
+                nickname = "该活动";
         }else{
             nickname = "【"+nickname+"】";
         }
@@ -356,4 +356,4 @@
     }else {
         Feng.confirm("Apakah Anda pasti akan mengekspor informasi kendaraan?", operation);
     }
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js b/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js
index 4030ebb..ee2b7bc 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tCompetition/tCompetition_info.js
@@ -221,7 +221,7 @@
         console.log("选中平台")
         console.log($("#pCode1").val())
         console.log($("#cCode1").val())
-        // 选中平台赛事
+        // 选中平台活动
         pCode = $("#pCode1").val();
         if($("#pCode1").val()==""){
             Feng.info("请选择省");
@@ -236,7 +236,7 @@
         console.log("选中运营商")
         console.log($("#pCode").val())
         console.log($("#cCode").val())
-        // 选中运营商赛事
+        // 选中运营商活动
         pCode = $("#pCode").val();
         if(pCode==""){
             Feng.info("请选择省");
@@ -271,7 +271,7 @@
     var shopIdString = shopId.join(",");
     var name = $("#name").val();
     if(name==""){
-        Feng.info("请输入赛事名称");
+        Feng.info("请输入活动名称");
         return;
     }
     var startTime = $("#startTime").val();
@@ -306,13 +306,13 @@
     let realName = document.querySelector('input[name="realName"]:checked').value;
     var introduction = $("#introduction").val();
     if(introduction==""){
-        Feng.info("请输入赛事简介");
+        Feng.info("请输入活动简介");
         return;
     }
 
     var goodImgs = TCarInfoDlg.goodsPicArray1;
     if(goodImgs.length==0){
-        Feng.info("请上传赛事活动图片")
+        Feng.info("请上传活动图片")
         return;
     }
     var imgOne ="";
@@ -407,7 +407,7 @@
 
     var name = $("#name").val();
     if(name==""){
-        Feng.info("请输入赛事名称");
+        Feng.info("请输入活动名称");
         return;
     }
     var startTime = $("#startTime").val();
@@ -422,6 +422,11 @@
         return;
     }
     var registerEndTime = $("#registerEndTime").val();
+    if(registerEndTime==""){
+        Feng.info("请选择截止报名时间");
+        return;
+    }
+    let registerCondition = document.querySelector('input[name="registerCondition"]:checked').value;
     var startAge = $("#startAge").val();
     var endAge = $("#endAge").val();
     var cashPrice = $("#cashPrice").val();
@@ -441,14 +446,14 @@
     let realName = document.querySelector('input[name="realName"]:checked').value;
     var introduction = $("#introduction").val();
     if(introduction==""){
-        Feng.info("请输入赛事简介");
+        Feng.info("请输入活动简介");
         return;
     }
 
     var goodImgs = TCarInfoDlg.goodsPicArray1;
 
     if(goodImgs.length==0){
-        Feng.info("请上传赛事活动图片")
+        Feng.info("请上传活动图片")
         return;
     }
     var imgOne ="";
@@ -494,6 +499,7 @@
     ajax.set("startTime",startTime);
     ajax.set("endTime",endTime);
     ajax.set("registerEndTime",registerEndTime);
+    ajax.set("registerCondition",registerCondition);
     ajax.set("startAge",startAge);
     ajax.set("endAge",endAge);
     ajax.set("cashPrice",cashPrice);
@@ -881,4 +887,4 @@
             }
         });
     })
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition.js b/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition.js
index 3ce4666..e0a7355 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition.js
@@ -20,7 +20,7 @@
         {title: '所在市', field: 'city', visible: true, align: 'center', valign: 'middle'},
         {title: '举办门店', field: 'storeName', visible: true, align: 'center', valign: 'middle',width:'8%',
         },
-        {title:  '赛事名称', field: 'name', visible: true, align: 'center', valign: 'middle',width:'8%',
+        {title:  '活动名称', field: 'name', visible: true, align: 'center', valign: 'middle',width:'8%',
         },
         {title: '开始时间', field: 'startTime', visible: true, align: 'center', valign: 'middle',width:'8%',
         },
@@ -108,12 +108,12 @@
 TCompetition.openTCompetitionDetail = function () {
     if (this.check()) {
         if (TCompetition.seItem.auditStatus == 3){
-            Feng.error("当前赛事不可以再审核");
+            Feng.error("当前活动不可以再审核");
             return;
         }
         var index = layer.load(1,{
             type: 1
-            , title: '赛事审核'
+            , title: '活动审核'
             , area: ['50%', '50%']
             , offset: 'auto' //具体配置参考:http://www.layui.com/doc/modules/layer.html#offset
             , id: 'layerDemo' //防止重复弹出cge
@@ -144,7 +144,7 @@
             },
             btn2:function () {
                 if (TCompetition.seItem.auditStatus==3){
-                    Feng.info("该赛事不可再次审核")
+                    Feng.info("该活动不可再次审核")
                     return false;
                 }
                 let audit = document.querySelector('input[name="r1"]:checked').value;
@@ -427,4 +427,4 @@
     }else {
         Feng.confirm("Apakah Anda pasti akan mengekspor informasi kendaraan?", operation);
     }
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition_info.js b/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition_info.js
index 661344e..d76ad9f 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition_info.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tCompetitionAudit/tCompetition_info.js
@@ -175,7 +175,7 @@
     var shopId = $("#shopId").val();
     var name = $("#name").val();
     if(name==""){
-        Feng.info("请输入赛事名称");
+        Feng.info("请输入活动名称");
         return;
     }
     var startTime = $("#startTime").val();
@@ -210,7 +210,7 @@
     let realName = document.querySelector('input[name="realName"]:checked').value;
     var introduction = $("#introduction").val();
     if(introduction==""){
-        Feng.info("请输入赛事简介");
+        Feng.info("请输入活动简介");
         return;
     }
 
@@ -290,7 +290,7 @@
     var shopId = $("#shopId").val();
     var name = $("#name").val();
     if(name==""){
-        Feng.info("请输入赛事名称");
+        Feng.info("请输入活动名称");
         return;
     }
     var startTime = $("#startTime").val();
@@ -325,7 +325,7 @@
     let realName = document.querySelector('input[name="realName"]:checked').value;
     var introduction = $("#introduction").val();
     if(introduction==""){
-        Feng.info("请输入赛事简介");
+        Feng.info("请输入活动简介");
         return;
     }
 
@@ -612,4 +612,4 @@
             }
         });
     })
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tEnsureIncomeRule/tEnsureIncomeRule.js b/cloud-server-management/src/main/webapp/static/modular/system/tEnsureIncomeRule/tEnsureIncomeRule.js
index df4db58..6e55b96 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tEnsureIncomeRule/tEnsureIncomeRule.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tEnsureIncomeRule/tEnsureIncomeRule.js
@@ -172,14 +172,18 @@
  */
 TEnsureIncomeRule.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tEnsureIncomeRule/delete", function (data) {
             Feng.success("删除成功!");
             TEnsureIncomeRule.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tEnsureIncomeRuleId",this.seItem.id);
+        ajax.set("tEnsureIncomeRuleId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该规则?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/tFeedback.js b/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/tFeedback.js
index 14176dc..054dc12 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/tFeedback.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/tFeedback.js
@@ -197,14 +197,18 @@
  */
 TFeedback.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tFeedback/delete", function (data) {
              Feng.success("删除成功!");
             TFeedback.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tFeedbackId",this.seItem.id);
+        ajax.set("tFeedbackId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该反馈记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/userFeedback.js b/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/userFeedback.js
index a9afe35..5f64a00 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/userFeedback.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tFeedback/userFeedback.js
@@ -205,14 +205,18 @@
  */
 TUserFeedback.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tFeedback/delete", function (data) {
              Feng.success("删除成功!");
             TUserFeedback.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tFeedbackId",this.seItem.id);
+        ajax.set("tFeedbackId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该反馈记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tGoods/tPay_info.js b/cloud-server-management/src/main/webapp/static/modular/system/tGoods/tPay_info.js
index be93d35..cf69f17 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tGoods/tPay_info.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tGoods/tPay_info.js
@@ -23,6 +23,11 @@
                 return {1: "未使用", 2: "已核销"}[value]
             }
         },
+        {title: '入园方式', field: 'goType', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "手环", 2: "门票核销"}[value] || "-";
+            }
+        },
     ];
 };
 TPayInfo.openAddTSite = function () {
@@ -30,25 +35,21 @@
         if (TPayInfo.seItem.status === 2) {
             return Feng.error("该门票已核销!");
         }
+        // 门票管理页提供独立模板;其他复用该脚本的页面继续使用兼容的默认模板。
+        var entryMethodContent = $("#ticketEntryMethodTemplate").html() ||
+            '<div class="form-horizontal"><div class="col-sm-11"><div class="col-sm-11"><div class="form-group">' +
+            '<label class="col-sm-3 control-label">请选择:</label><div class="col-sm-9" style="margin-top: 5px;">' +
+            '<input type="radio" id="areaType1" value="1" name="areaType" checked><label for="areaType1">手环</label>' +
+            '<input type="radio" id="areaType2" value="2" name="areaType"><label for="areaType2">门票核销</label>' +
+            '</div></div></div></div></div>';
         var index = layer.load(1, {
             type: 1
             , title: '入园方式'
             , area: ['50%', '50%']
             , offset: 'auto' //具体配置参考:http://www.layui.com/doc/modules/layer.html#offset
             , id: 'layerDemo' //防止重复弹出cge
-            , content: '<div class="form-horizontal">' +
-                '                    <div class="col-sm-11" >' +
-                '                    <div class="col-sm-11">' +
-                '                        <div class="form-group">\n' +
-                '                            <label class="col-sm-3 control-label">请选择:</label>\n' +
-                '                         <div class="col-sm-9" style="margin-top: 5px;">\n' +
-                '                                  <input type="radio" id="areaType1" value="1" name="areaType"> ' +
-                '                            <label for="areaType1"> 手环 </label>\n' +
-                '                            </div>\n' +
-                '                        </div>\n' +
-                '                       </div>' +
-                '                   </div>' +
-                '</div>'
+            // 页面模板中集中维护选项文案与 goType 值,避免前后端页面出现两份配置。
+            , content: entryMethodContent
 
             , btn: ['确认', '关闭']
             , btnAlign: 'c' //按钮居中
@@ -58,14 +59,19 @@
                 layer.closeAll();
             },
             yes: function () {
-                console.log("看看id")
-                console.log(TPayInfo.seItem.id)
+                // 入园方式必须随核销请求提交,后端会保存该次核销所选方式。
+                var goType = $("input[name='areaType']:checked").val();
+                if (!goType) {
+                    return Feng.error("请选择入园方式!");
+                }
                 var ajax = new $ax(Feng.ctxPath + "/ticket/writeOff", function (data) {
                     TPayInfo.search();
-                    Feng.error("核销成功!")
+                    Feng.success("核销成功!");
                 }, function (data) {
+                    Feng.error("核销失败!" + (data.responseJSON ? data.responseJSON.message : ""));
                 });
                 ajax.set("id", TPayInfo.seItem.id);
+                ajax.set("goType", goType);
                 ajax.start();
                 layer.closeAll();
             }
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminAgreement/tHuiminAgreement.js b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminAgreement/tHuiminAgreement.js
index dce6040..5f75ab9 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminAgreement/tHuiminAgreement.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminAgreement/tHuiminAgreement.js
@@ -72,14 +72,18 @@
  */
 THuiminAgreement.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tHuiminAgreement/delete", function (data) {
             Feng.success("删除成功!");
             THuiminAgreement.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tHuiminAgreementId",this.seItem.id);
+        ajax.set("tHuiminAgreementId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该协议?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js
index fb3201a..a9379f1 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js
@@ -86,7 +86,7 @@
     }
     var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/addPayHuiMing", function(data){
         if (data==200){
-            Feng.success("录入成功")
+            Feng.success("赠送惠民卡录入成功")
             THuiminCardInfo.close()
             return
         }
@@ -95,4 +95,4 @@
     ajax.set("studentId",user);
     ajax.set("cardId",cardId);
     ajax.start();
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminRecord/tHuiminRecord.js b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminRecord/tHuiminRecord.js
index 9c7cb85..c443321 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminRecord/tHuiminRecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminRecord/tHuiminRecord.js
@@ -69,14 +69,18 @@
  */
 THuiminRecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tHuiminRecord/delete", function (data) {
             Feng.success("删除成功!");
             THuiminRecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tHuiminRecordId",this.seItem.id);
+        ajax.set("tHuiminRecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该惠民卡记录?", operation);
     }
 };
 
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 850d901..34103b0 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
@@ -20,6 +20,10 @@
                 formatter:function(value,row,index){
                     return {1: '年度卡', 2: '年内卡'}[value];
                 }},
+            {title: '订单类型', field: 'paymentType', visible: true, align: 'center', valign: 'middle',
+                formatter:function(value,row,index){
+                    return value === 3 ? '赠送' : '售卖';
+                }},
             {title: '售卖金额', field: 'salesMoney', visible: true, align: 'center', valign: 'middle'},
             {title: '支付流水号', field: 'orderNumber', visible: true, align: 'center', valign: 'middle'},
             {title: '所属运营商', field: 'operatorName', visible: true, align: 'center', valign: 'middle'},
@@ -114,14 +118,18 @@
  */
 TPayHuimin.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tPayHuimin/delete", function (data) {
             Feng.success("删除成功!");
             TPayHuimin.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tPayHuiminId",this.seItem.id);
+        ajax.set("tPayHuiminId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该惠民卡记录?", operation);
     }
 };
 TPayHuimin.getStaticsData = function (){
@@ -140,6 +148,10 @@
 }
 TPayHuimin.refund = function (){
     if (this.check()) {
+        if (TPayHuimin.seItem.paymentType === 3) {
+            Feng.error("赠送惠民卡不允许退款");
+            return;
+        }
         if (TPayHuimin.seItem.status == 3){
             Feng.error("该商品已退款");
             return;
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tQuestion/TQuestion.js b/cloud-server-management/src/main/webapp/static/modular/system/tQuestion/TQuestion.js
index 0a6bd57..befe4ec 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tQuestion/TQuestion.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tQuestion/TQuestion.js
@@ -206,6 +206,7 @@
         });
         data1.type = 3;
 
+        Feng.confirm("确认删除所选问题?", function () {
         $.ajax({
             url: Feng.ctxPath + "/tQuestion/changeState",
             type: "POST",
@@ -220,6 +221,7 @@
                 Feng.error(errorMessage);
             }
         });
+        });
     }
 };
 /**
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOther.js b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOther.js
index 9e2eddd..5d3183b 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOther.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOther.js
@@ -259,14 +259,18 @@
 };
 TCompetition.del = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tShop/del", function (data) {
             Feng.success("删除成功!");
             TCompetition.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("id",this.seItem.id);
+        ajax.set("id", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该店铺?", operation);
     }
 };
 TCompetition.unfreeze = function () {
@@ -674,4 +678,4 @@
     }else {
         Feng.confirm("Apakah Anda pasti akan mengekspor informasi kendaraan?", operation);
     }
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherOne.js b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherOne.js
index be97dd6..cc8377d 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherOne.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherOne.js
@@ -79,6 +79,7 @@
 
 TCompetition.delete1= function (e) {
     console.log(e)
+    var operation = function () {
     var ajax = new $ax(Feng.ctxPath + "/tShop/deleteTwo", function (data) {
         Feng.success("删除成功!");
         TCompetition.table.refresh();
@@ -87,6 +88,8 @@
     });
     ajax.set("id",e);
     ajax.start();
+    };
+    Feng.confirm("确认删除该记录?", operation);
 }
 /**
  * 检查是否选中
@@ -774,4 +777,4 @@
 
 TCompetition.close = function() {
     parent.layer.close(window.parent.TCompetition.layerIndex);
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherTwo.js b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherTwo.js
index e8e2304..d494c5d 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherTwo.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShopOtherTwo.js
@@ -78,6 +78,7 @@
 
 TCompetition.delete1= function (e) {
     console.log(e)
+    var operation = function () {
     var ajax = new $ax(Feng.ctxPath + "/tShop/deleteTwo", function (data) {
         Feng.success("删除成功!");
         TCompetition.table.refresh();
@@ -86,6 +87,8 @@
     });
     ajax.set("id",e);
     ajax.start();
+    };
+    Feng.confirm("确认删除该记录?", operation);
 }
 /**
  * 检查是否选中
@@ -922,4 +925,4 @@
 }
 TCompetition.close = function() {
     parent.layer.close(window.parent.TCompetition.layerIndex);
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info.js b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info.js
index f59a69c..66e528b 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info.js
@@ -284,26 +284,6 @@
         Feng.info("请填写门店介绍")
         return;
     }
-    let userName = $("#userName").val()
-
-    if(userName==''){
-        Feng.info("请输入店长姓名")
-        return;
-    }
-
-
-    let userPhone = $("#userPhone").val()
-    if (!phonePattern.test(userPhone)) {
-
-        Feng.info("请输入正确手机号")
-        return false;
-    }
-
-
-    if(userPhone==''){
-        Feng.info("请输入店长手机号")
-        return;
-    }
     let img = $("#img").val()
 
     if(img==''){
@@ -326,13 +306,9 @@
     }
     //提交信息
     var ajax = new $ax(Feng.ctxPath + "/tShop/add", function(data){
-        if(data=="5001"){
-            Feng.error("该店长手机号已经存在!")
-        }else{
-            Feng.success("添加成功!");
-            window.parent.TCompetition.table.refresh();
-            TCarInfoDlg.close();
-        }
+        Feng.success("添加成功!");
+        window.parent.TCompetition.table.refresh();
+        TCarInfoDlg.close();
     });
     ajax.set(this.tCarInfoData);
     ajax.set("provinceCode",pCode);
@@ -343,8 +319,6 @@
     ajax.set("address",address);
     ajax.set("time",time);
     ajax.set("introduce",introduce);
-    ajax.set("userName",userName);
-    ajax.set("userPhone",userPhone);
     ajax.set("coverDrawing",img);
     ajax.set("realPicture",imgOne);
     ajax.set("lat",$("#latitude").val());
@@ -541,23 +515,6 @@
         Feng.info("请填写门店介绍")
         return;
     }
-    let userName = $("#userName").val()
-
-    if(userName==''){
-        Feng.info("请输入店长姓名")
-        return;
-    }
-    let userPhone = $("#userPhone").val()
-
-    if (!phonePattern.test(userPhone)) {
-        Feng.info("请输入合法手机号")
-        return ;
-    }
-
-    if(userPhone==''){
-        Feng.info("请输入店长手机号")
-        return;
-    }
     let img = $("#img").val()
 
 
@@ -581,9 +538,7 @@
 
     //提交信息
     var ajax = new $ax(Feng.ctxPath + "/tShop/update", function(data){
-        if(data=="5001"){
-            Feng.error("该店长手机号已经存在!")
-        }else if(data.code == 200){
+        if(data.code == 200){
             if(language==1){
                 Feng.success("修改成功!");
             }else if(language==2){
@@ -608,8 +563,6 @@
     ajax.set("address",address);
     ajax.set("time",time);
     ajax.set("introduce",introduce);
-    ajax.set("userName",userName);
-    ajax.set("userPhone",userPhone);
     ajax.set("coverDrawing",img);
     ajax.set("realPicture",imgOne);
     ajax.set("lat",$("#latitude").val());
@@ -989,4 +942,4 @@
     });
     ajax.set("oneId",oneId);
     ajax.start();
-}
\ No newline at end of file
+}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info_one.js b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info_one.js
index 2d4e403..17b83e5 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info_one.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tShop/tShop_info_one.js
@@ -216,18 +216,6 @@
         Feng.info("请填写门店介绍")
         return;
     }
-    let userName = $("#userName").val()
-
-    if(userName==''){
-        Feng.info("请输入店长姓名")
-        return;
-    }
-    let userPhone = $("#userPhone").val()
-
-    if(userPhone==''){
-        Feng.info("请输入店长手机号")
-        return;
-    }
     let img = $("#img").val()
 
     if(img==''){
@@ -250,9 +238,6 @@
     }
     //提交信息
     var ajax = new $ax(Feng.ctxPath + "/tShop/add", function(data){
-        if(data=="5001"){
-            Feng.error("该店长手机号已经存在!")
-        }else
         if(data.code == 200){
             if(language==1){
                 Feng.success("添加成功!");
@@ -279,8 +264,6 @@
     ajax.set("address",address);
     ajax.set("time",time);
     ajax.set("introduce",intro);
-    ajax.set("userName",userName);
-    ajax.set("userPhone",userPhone);
     ajax.set("coverDrawing",img);
     ajax.set("realPicture",imgOne);
     ajax.set("lat",$("#latitude").val());
@@ -448,18 +431,6 @@
         Feng.info("请填写门店介绍")
         return;
     }
-    let userName = $("#userName").val()
-
-    if(userName==''){
-        Feng.info("请输入店长姓名")
-        return;
-    }
-    let userPhone = $("#userPhone").val()
-
-    if(userPhone==''){
-        Feng.info("请输入店长手机号")
-        return;
-    }
     let img = $("#img").val()
 
 
@@ -471,9 +442,6 @@
     }
     //提交信息
     var ajax = new $ax(Feng.ctxPath + "/tShop/update", function(data){
-        if(data=="5001"){
-            Feng.error("该店长手机号已经存在!")
-        }else
         if(data.code == 200){
             if(language==1){
                 Feng.success("修改成功!");
@@ -498,8 +466,6 @@
     ajax.set("address",address);
     ajax.set("time",time);
     ajax.set("introduce",intro);
-    ajax.set("userName",userName);
-    ajax.set("userPhone",userPhone);
     ajax.set("coverDrawing",img);
     ajax.set("realPicture",imgOne);
     ajax.set("id",$("#id").val());
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tSite/tSiteLock.js b/cloud-server-management/src/main/webapp/static/modular/system/tSite/tSiteLock.js
index 6f05a07..0cb8b34 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tSite/tSiteLock.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tSite/tSiteLock.js
@@ -53,20 +53,23 @@
  * 删除
  */
 TSiteLock.delete = function(e) {
-    $(e).parent().parent().remove();
-    $.ajax({
-        url: Feng.ctxPath + "/tSite/deleteSiteLock/"+e.id,
-        type: "POST",
-        contentType: "application/json", // 设置请求头的 Content-Type
-        success: function(response) {
-            Feng.success("删除成功!");
-            TSite.search();
-        },
-        error: function(xhr, status, error) {
-            var errorMessage = xhr.responseText ? xhr.responseText : "删除失败!";
-            Feng.error("您的网络异常!");
-        }
-    });
+    var operation = function () {
+        $.ajax({
+            url: Feng.ctxPath + "/tSite/deleteSiteLock/"+e.id,
+            type: "POST",
+            contentType: "application/json", // 设置请求头的 Content-Type
+            success: function(response) {
+                $(e).parent().parent().remove();
+                Feng.success("删除成功!");
+                TSite.search();
+            },
+            error: function(xhr, status, error) {
+                var errorMessage = xhr.responseText ? xhr.responseText : "删除失败!";
+                Feng.error("您的网络异常!");
+            }
+        });
+    };
+    Feng.confirm("确认删除该场地锁定记录?", operation);
 }
 
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tSmsrecord/tSmsrecord.js b/cloud-server-management/src/main/webapp/static/modular/system/tSmsrecord/tSmsrecord.js
index e86b4b8..9e0402d 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tSmsrecord/tSmsrecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tSmsrecord/tSmsrecord.js
@@ -123,14 +123,18 @@
  */
 TSmsrecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tSmsrecord/delete", function (data) {
              Feng.success("删除成功!");
             TSmsrecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tSmsrecordId",this.seItem.id);
+        ajax.set("tSmsrecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该短信记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent.js b/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent.js
index 35f1324..cce249b 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent.js
@@ -153,14 +153,18 @@
  */
 TStudent.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tStudent/delete", function (data) {
             Feng.success("删除成功!");
             TStudent.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tStudentId",this.seItem.id);
+        ajax.set("tStudentId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent_commite.js b/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent_commite.js
index 1e577c5..5788dd9 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent_commite.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tStudent/tStudent_commite.js
@@ -110,14 +110,18 @@
  */
 TStudent.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tStudent/delete", function (data) {
             Feng.success("删除成功!");
             TStudent.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tStudentId",this.seItem.id);
+        ajax.set("tStudentId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tUserExit/tbUserExit.js b/cloud-server-management/src/main/webapp/static/modular/system/tUserExit/tbUserExit.js
index e0fab4f..6f531e5 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tUserExit/tbUserExit.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tUserExit/tbUserExit.js
@@ -209,7 +209,8 @@
             });
             ajax.set("TUserExitId", a);
             ajax.start();
-        }
+        };
+        Feng.confirm("确认删除该用户退出记录?", operation);
     }
 };
 TUserExit.start = function () {
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tUserRedPacketRecord/tUserRedPacketRecord.js b/cloud-server-management/src/main/webapp/static/modular/system/tUserRedPacketRecord/tUserRedPacketRecord.js
index 17c3170..840dff6 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tUserRedPacketRecord/tUserRedPacketRecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tUserRedPacketRecord/tUserRedPacketRecord.js
@@ -110,14 +110,18 @@
  */
 TUserRedPacketRecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/tUserRedPacketRecord/delete", function (data) {
              Feng.success("删除成功!");
             TUserRedPacketRecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("tUserRedPacketRecordId",this.seItem.id);
+        ajax.set("tUserRedPacketRecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该红包记录?", operation);
     }
 };
 
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/user/user.js b/cloud-server-management/src/main/webapp/static/modular/system/user/user.js
index da1d9f2..591131d 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/user/user.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/user/user.js
@@ -121,6 +121,27 @@
     }
 };
 
+/** The button is rendered only for admin; the API repeats the permission check and records an audit event. */
+MgrUser.viewSensitiveData = function () {
+    if (!this.check()) return;
+    layer.confirm('查看完整手机号和身份证号将记录审计日志,是否继续?', {icon: 3, title: '敏感信息查看'}, function (index) {
+        $.ajax({
+            url: Feng.ctxPath + '/system/sensitive/employee/' + MgrUser.seItem.id,
+            type: 'GET',
+            success: function (data) {
+                if (!data) { Feng.info('未查询到员工信息'); return; }
+                var html = '<div style="padding:20px;line-height:28px">'
+                    + '<div>姓名:' + (data.name || '') + '</div>'
+                    + '<div>手机号:' + (data.phone || '') + '</div>'
+                    + '<div>身份证号:' + (data.idCard || '') + '</div></div>';
+                layer.open({type: 1, title: '员工敏感信息(已记录审计日志)', area: ['420px', '260px'], content: html});
+            },
+            error: function () { Feng.error('无权查看敏感信息或查询失败'); }
+        });
+        layer.close(index);
+    });
+};
+
 /**
  * 点击角色分配
  * @param
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/user/user_info.js b/cloud-server-management/src/main/webapp/static/modular/system/user/user_info.js
index 372195a..e4d3b01 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/user/user_info.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/user/user_info.js
@@ -77,9 +77,16 @@
                     }
                 });
             }
-            this.userInfoData[key] = ids;
+            // 不提交不存在控件或未选择控件的空字符串,避免后端把 "" 转 Integer 时抛异常。
+            if (ids !== "") {
+                this.userInfoData[key] = ids;
+            }
         }else{
-            this.userInfoData[key]= $("#" + key).val();
+            var value = $("#" + key).val();
+            // 新增页 id 为空、多选门店未选中时均不应提交为 key=""。
+            if (value !== null && value !== "") {
+                this.userInfoData[key] = value;
+            }
         }
     }
 
@@ -161,7 +168,13 @@
  */
 UserInfoDlg.collectData = function () {
     this.set('id').set('account').set('sex').set('password').set('avatar').set("deptid")
-        .set('email').set('name').set('birthday').set('rePassword').set('roleid').set('phone').set('idCard');
+        .set('email').set('name').set('birthday').set('rePassword').set('roleid').set('phone').set('idCard').set('storeIds');
+
+    // jQuery 默认会把数组编码为 storeIds[]=1&storeIds[]=2;Spring 对 List<Integer>
+    // 无法解析空下标 "[]"。转成逗号分隔值后,Spring 会自动绑定为 List<Integer>。
+    if ($.isArray(this.userInfoData.storeIds)) {
+        this.userInfoData.storeIds = this.userInfoData.storeIds.join(',');
+    }
 };
 
 /**
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/userActivity/userActivity.js b/cloud-server-management/src/main/webapp/static/modular/system/userActivity/userActivity.js
index 58aee7d..44faf16 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/userActivity/userActivity.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/userActivity/userActivity.js
@@ -199,14 +199,18 @@
  */
 UserActivity.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/userActivity/delete", function (data) {
              Feng.success("删除成功!");
             UserActivity.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("userActivityId",this.seItem.id);
+        ajax.set("userActivityId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该活动?", operation);
     }
 };
 /**
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/userCouponRecord/userCouponRecord.js b/cloud-server-management/src/main/webapp/static/modular/system/userCouponRecord/userCouponRecord.js
index 89f7907..37c1ab8 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/userCouponRecord/userCouponRecord.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/userCouponRecord/userCouponRecord.js
@@ -153,14 +153,18 @@
  */
 UserCouponRecord.delete = function () {
     if (this.check()) {
+        var selectedId = this.seItem.id;
+        var operation = function () {
         var ajax = new $ax(Feng.ctxPath + "/userCouponRecord/delete", function (data) {
              Feng.success("删除成功!");
             UserCouponRecord.table.refresh();
         }, function (data) {
             Feng.error("删除失败!" + data.responseJSON.message + "!");
         });
-        ajax.set("userCouponRecordId",this.seItem.id);
+        ajax.set("userCouponRecordId", selectedId);
         ajax.start();
+        };
+        Feng.confirm("确认删除该优惠券记录?", operation);
     }
 };
 
diff --git a/cloud-server-other/src/main/java/com/dsh/OtherApplication.java b/cloud-server-other/src/main/java/com/dsh/OtherApplication.java
index a21a0d8..554ff58 100644
--- a/cloud-server-other/src/main/java/com/dsh/OtherApplication.java
+++ b/cloud-server-other/src/main/java/com/dsh/OtherApplication.java
@@ -22,7 +22,7 @@
  */
 @EnableSwagger2
 @EnableScheduling
-@EnableFeignClients
+@EnableFeignClients(defaultConfiguration = com.dsh.other.audit.FeignAuditConfiguration.class)
 @MBCloudApplication
 @Import({WebConfig.class})
 @MapperScan("com.dsh.other.mapper")
diff --git a/cloud-server-other/src/main/java/com/dsh/config/MyLocaleResolver.java b/cloud-server-other/src/main/java/com/dsh/config/MyLocaleResolver.java
index f622477..41404b1 100644
--- a/cloud-server-other/src/main/java/com/dsh/config/MyLocaleResolver.java
+++ b/cloud-server-other/src/main/java/com/dsh/config/MyLocaleResolver.java
@@ -19,11 +19,11 @@
         //1=中文,2=英文,3=印尼文
         String language = getQueryParams(request, "language");
 
-        Locale locale = null;
+        Locale locale;
         if (StringUtils.isEmpty(language)) {
-            locale = Locale.getDefault();
+            return Locale.getDefault();
         }
-        //如果请求不为空
+        // language 已非空;未识别值沿用历史行为,默认印尼语。
         if (language.equals("1")) {
             locale = new Locale("zh", "CN");
         } else if (language.equals("2")) {
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/BallController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/BallController.java
index 84b2775..67c9118 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/BallController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/BallController.java
@@ -59,7 +59,9 @@
         }else{
             List<Integer> gameIds = gameService.list(new QueryWrapper<Game>().eq("storeId", query.getStoreId()))
                     .stream().map(Game::getId).collect(Collectors.toList());
-            QueryWrapper wrapper = new QueryWrapper<TGameRecord>().eq("status", 1).eq("payType", 1).eq("payType", 2);
+            QueryWrapper<TGameRecord> wrapper = new QueryWrapper<TGameRecord>()
+                    .eq("status", 1)
+                    .in("payType", 1, 2);
             if(gameIds.size() > 0){
                 wrapper.in("gameId", gameIds);
             }
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
index ef74165..1fe0c96 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
@@ -9,6 +9,10 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.dsh.other.entity.*;
+import com.dsh.other.enums.EnableStatusEnum;
+import com.dsh.other.enums.QrLinkTypeEnum;
+import com.dsh.other.enums.SiteBookingStatusEnum;
+import com.dsh.other.mapper.QrLinkMapper;
 import com.dsh.other.feignclient.CourseRecordClient;
 import com.dsh.other.feignclient.account.CityManagerClient;
 import com.dsh.other.feignclient.activity.UserCouponClient;
@@ -29,6 +33,7 @@
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -46,6 +51,7 @@
 import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.util.*;
+import java.security.SecureRandom;
 import java.util.stream.Collectors;
 
 /**
@@ -54,7 +60,11 @@
  */
 @RestController
 @RequestMapping("")
+@Slf4j
 public class SiteController {
+
+    private static final char[] ENTRY_CODE_CHARS = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
+    private final SecureRandom entryCodeRandom = new SecureRandom();
 
     @Autowired
     private ISiteService siteService;
@@ -70,6 +80,9 @@
 
     @Autowired
     private ISiteBookingService siteBookingService;
+
+    @Resource
+    private QrLinkMapper qrLinkMapper;
 
     @Resource
     private UserCouponClient userCouponClient;
@@ -155,7 +168,10 @@
     @RequestMapping("/base/site/getList")
     @ResponseBody
     public List<Site> getList() {
-        return siteService.list(new QueryWrapper<Site>().ne("state", 3));
+        return siteService.list(new QueryWrapper<Site>()
+                .ne("state", 3)
+                .orderByDesc("insertTime")
+                .orderByDesc("id"));
     }
 
     /**
@@ -523,16 +539,20 @@
                 String trade_no = map.get("trade_no");
                 SiteBooking siteBooking = siteBookingService.getOne(new QueryWrapper<SiteBooking>()
                         .eq("orderNo", code).eq("state", 1));
+                if (siteBooking == null) {
+                    throw new IllegalStateException("未找到支付宝回调对应的场地预约订单:" + code);
+                }
                 if (siteBooking.getStatus() == 0) {
                     siteBooking.setPayTime(new Date());
                     siteBooking.setStatus(1);
                     siteBooking.setPayOrderNo(trade_no);
                     siteBookingService.updateById(siteBooking);
-                    PrintWriter out = response.getWriter();
-                    out.write("success");
-                    out.flush();
-                    out.close();
                 }
+                // 已处理的重复通知也必须确认 success,避免支付宝持续重试。
+                PrintWriter out = response.getWriter();
+                out.write("success");
+                out.flush();
+                out.close();
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -698,6 +718,69 @@
         }
     }
 
+    @ResponseBody
+    @GetMapping("/api/site/entryQr")
+    @ApiOperation(value = "获取订场进场二维码", tags = {"用户—预约场地"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "预约数据 id", name = "bookingId", dataType = "int", required = true),
+            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header")
+    })
+    public ResultUtil<Map<String, Object>> entryQr(Integer bookingId) {
+        try {
+            Integer uid = tokenUtil.getUserIdFormRedis();
+            if (uid == null) return ResultUtil.tokenErr();
+            SiteBooking booking = siteBookingService.getById(bookingId);
+            if (booking == null || !uid.equals(booking.getAppUserId())) return ResultUtil.error("预约记录不存在");
+            if (SiteBookingStatusEnum.EXPIRED.getCode().equals(booking.getStatus())
+                    || SiteBookingStatusEnum.CANCELED.getCode().equals(booking.getStatus())) {
+                return ResultUtil.error("当前预约不可使用二维码");
+            }
+            QrLink link = qrLinkMapper.selectOne(new QueryWrapper<QrLink>()
+                    .eq("type", QrLinkTypeEnum.BOOKING_ENTRY.getCode())
+                    .eq("bookingId", bookingId)
+                    .eq("enabled", EnableStatusEnum.ENABLED.getCode())
+                    .last("limit 1"));
+            if (link == null || (link.getExpiresAt() != null && link.getExpiresAt().before(new Date()))) {
+                link = createEntryQrLink(booking, bookingId);
+            }
+            Map<String, Object> data = new HashMap<>();
+            data.put("shortCode", link.getShortCode());
+            data.put("url", "https://online.daowepark.com/other/q/" + link.getShortCode());
+            data.put("expiresAt", link.getExpiresAt());
+            return ResultUtil.success(data);
+        } catch (Exception e) {
+            log.error("[SITE_ENTRY_QR] generate failed, bookingId={}", bookingId, e);
+            return ResultUtil.runErr();
+        }
+    }
+
+    /** 创建与预约记录绑定的进场二维码短链。 */
+    private QrLink createEntryQrLink(SiteBooking booking, Integer bookingId) {
+        QrLink link = new QrLink();
+        link.setType(QrLinkTypeEnum.BOOKING_ENTRY.getCode());
+        link.setBookingId(bookingId);
+        link.setStoreId(booking.getStoreId());
+        link.setSiteId(booking.getSiteId());
+        link.setEnabled(EnableStatusEnum.ENABLED.getCode());
+        link.setExpiresAt(booking.getEndTime());
+        link.setShortCode(nextEntryQrCode());
+        qrLinkMapper.insert(link);
+        return link;
+    }
+
+    /** 生成数据库中尚未使用的十位进场二维码短码。 */
+    private String nextEntryQrCode() {
+        String code;
+        do {
+            StringBuilder builder = new StringBuilder(10);
+            for (int index = 0; index < 10; index++) {
+                builder.append(ENTRY_CODE_CHARS[entryCodeRandom.nextInt(ENTRY_CODE_CHARS.length)]);
+            }
+            code = builder.toString();
+        } while (qrLinkMapper.selectCount(new QueryWrapper<QrLink>().eq("shortCode", code)) > 0);
+        return code;
+    }
+
     public List<Integer> getIds(Integer siteId) {
         HttpRequest httpRequest = HttpRequest.get("https://port.daowepark.com/v7/user_api/general/get_space_area?space_id=" + siteId);
         HttpResponse execute = httpRequest.execute();
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/TPhoneController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/TPhoneController.java
index 6a0de47..3f782d7 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/TPhoneController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/TPhoneController.java
@@ -30,7 +30,9 @@
     @RequestMapping(value = "/base/phone/list")
     @ResponseBody
     public List<Phone> list() {
-        return phoneService.list(new QueryWrapper<>());
+        return phoneService.list(new QueryWrapper<Phone>()
+                .orderByDesc("insertTime")
+                .orderByDesc("id"));
     }
 
     /**
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/TVipController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/TVipController.java
index 35c530b..14eed78 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/TVipController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/TVipController.java
@@ -46,7 +46,11 @@
     @ResponseBody
     @PostMapping("/listAll")
     public List<Vip> listAll() {
-        List<Vip> list = vipService.lambdaQuery().eq(Vip::getStatus, 1).list();
+        List<Vip> list = vipService.lambdaQuery()
+                .eq(Vip::getStatus, 1)
+                .orderByDesc(Vip::getInsertTime)
+                .orderByDesc(Vip::getId)
+                .list();
         List<Coupon> coupons = couponClient.queryCouponAll();
         List<CouponCity> couponCityList = couponClient.queryAllCity();
         List<PointsMerchandise> pointsMerchandiseList = couponClient.queryAllPointGoods();
diff --git a/cloud-server-other/src/main/java/com/dsh/other/model/SiteBookingQuery.java b/cloud-server-other/src/main/java/com/dsh/other/model/SiteBookingQuery.java
index 4e060e0..0c9b3c0 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/model/SiteBookingQuery.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/model/SiteBookingQuery.java
@@ -18,4 +18,6 @@
     private List<Integer> userIds;
     // 门店ids
     private List<Integer> storeIds;
+    /** 是否包含已取消并退款的预约记录 */
+    private Boolean includeRefund;
 }
diff --git a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java
index c60af91..d650bdc 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java
@@ -9,7 +9,6 @@
 import com.alipay.api.DefaultAlipayClient;
 import com.alipay.api.request.AlipayTradeOrderSettleRequest;
 import com.alipay.api.response.AlipayTradeOrderSettleResponse;
-import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -978,59 +977,6 @@
         }
         ResultUtil alipay = payMoneyUtil.alipay(smid1, "预约场地", "预约场地", id.toString(), code, paymentPrice.toString(), "/base/site/aliPaymentSiteCallback");
         System.out.println("预约场地----" + alipay.getCode());
-        if (alipay.getCode() == 200) {
-            String finalSmid = smid1;
-            new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        int num = 1;
-                        int wait = 0;
-                        while (num <= 10) {
-                            int min = 5000;
-                            wait += (min * num);
-                            Thread.sleep(wait);
-                            SiteBooking siteBooking = siteBookingService.getById(id);
-                            if (siteBooking.getStatus() != 0) {
-                                break;
-                            }
-                            AlipayTradeQueryResponse resultUtil = payMoneyUtil.queryALIOrder(code);
-                            if (resultUtil.getCode().equals("10000") && siteBooking.getStatus() == 0) {
-                                /**
-                                 * WAIT_BUYER_PAY(交易创建,等待买家付款)、
-                                 * TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、
-                                 * TRADE_SUCCESS(交易支付成功)、
-                                 * TRADE_FINISHED(交易结束,不可退款)
-                                 */
-//                                Map<String, String> data1 = resultUtil.getData();
-//                                String s = data1.get("tradeStatus");
-                                String tradeNo = resultUtil.getTradeNo();
-                                String s = resultUtil.getTradeStatus();
-                                System.out.println("ssssss" + s);
-                                if ("TRADE_CLOSED".equals(s) || "TRADE_FINISHED".equals(s) || num == 10) {
-                                    break;
-                                }
-                                if ("TRADE_SUCCESS".equals(s)) {
-                                    siteBooking.setPayTime(new Date());
-                                    siteBooking.setStatus(1);
-                                    siteBooking.setPayOrderNo(tradeNo);
-                                    siteBookingService.updateById(siteBooking);
-                                    System.err.println("======完成支付");
-                                    Thread.sleep(30000);
-                                    payMoneyUtil.confirm(finalSmid, code, tradeNo, paymentPrice.toString());
-                                    break;
-                                }
-                                if ("WAIT_BUYER_PAY".equals(s)) {
-                                    num++;
-                                }
-                            }
-                        }
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-            }).start();
-        }
         return alipay;
     }
 
diff --git a/cloud-server-other/src/main/resources/mapper/SiteBookingMapper.xml b/cloud-server-other/src/main/resources/mapper/SiteBookingMapper.xml
index 90d3741..e153540 100644
--- a/cloud-server-other/src/main/resources/mapper/SiteBookingMapper.xml
+++ b/cloud-server-other/src/main/resources/mapper/SiteBookingMapper.xml
@@ -41,8 +41,12 @@
             <if test="sTime !=null and sTime!= '' and eTime !=null and eTime!= ''">
                 and t1.insertTime between #{sTime} and #{eTime}
             </if>
-        and t1.status !=0 and t1.status !=5
+        and t1.status != 0
+        <if test="query.includeRefund == null or !query.includeRefund">
+            and t1.status != 5
+        </if>
         </where>
+        order by t1.insertTime desc, t1.id desc
     </select>
     <select id="queryByCode" resultType="java.lang.Integer">
         SELECT  storeId
diff --git a/sql/playpai_other.sql b/sql/playpai_other.sql
index cd6c782..8d66090 100644
--- a/sql/playpai_other.sql
+++ b/sql/playpai_other.sql
@@ -416,13 +416,13 @@
 INSERT INTO `sys_menu` VALUES (285, '/bodySideAppointment', 'welfare', '[0],[welfare],', '体测预约管理', 'fa-bars', '/bodySideAppointment', 9, 2, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (286, '/bodySideAppointment/add', '/bodySideAppointment', '[0],[welfare],[/bodySideAppointment],', '添加', 'fa-bars', '/bodySideAppointment/add', 2, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (287, '/bodySideAppointment/update', '/bodySideAppointment', '[0],[welfare],[/bodySideAppointment],', '编辑', 'fa-bars', '/bodySideAppointment/update', 3, 3, 0, NULL, 1, NULL);
-INSERT INTO `sys_menu` VALUES (288, 'competition', '0', '[0],', '赛事', 'fa-bars', '#', 7, 1, 1, NULL, 1, NULL);
-INSERT INTO `sys_menu` VALUES (289, '/tCompetition', 'competition', '[0],[competition],', '赛事活动管理', 'fa-bars', '/tCompetition', 1, 2, 1, NULL, 1, NULL);
+INSERT INTO `sys_menu` VALUES (288, 'competition', '0', '[0],', '活动', 'fa-bars', '#', 7, 1, 1, NULL, 1, NULL);
+INSERT INTO `sys_menu` VALUES (289, '/tCompetition', 'competition', '[0],[competition],', '活动管理', 'fa-bars', '/tCompetition', 1, 2, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (290, '/tCompetition/tCompetition_user', '/tCompetition', '[0],[competition],[/tCompetition],', '已报名人员', 'fa-bars', '/tCompetition/tCompetition_user', 6, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (291, '/tCompetition/tCompetition_add', '/tCompetition', '[0],[competition],[/tCompetition],', '添加', 'fa-bars', '/tCompetition/tCompetition_add', 2, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (292, '/tCompetition/tCompetition_update', '/tCompetition', '[0],[competition],[/tCompetition],', '编辑', 'fa-bars', '/tCompetition/tCompetition_update', 3, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (293, '/tCompetition/tCompetition_info', '/tCompetition', '[0],[competition],[/tCompetition],', '查看详情', 'fa-bars', '/tCompetition/tCompetition_update', 5, 3, 0, NULL, 1, NULL);
-INSERT INTO `sys_menu` VALUES (294, '/tCompetitionAudit', 'competition', '[0],[competition],', '赛事活动审核', 'fa-bars', '/tCompetitionAudit', 2, 2, 1, NULL, 1, NULL);
+INSERT INTO `sys_menu` VALUES (294, '/tCompetitionAudit', 'competition', '[0],[competition],', '活动审核', 'fa-bars', '/tCompetitionAudit', 2, 2, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (295, '/tCompetitionAudit/tCompetition_update', '/tCompetitionAudit', '[0],[competition],[/tCompetitionAudit],', '查看详情', 'fa-bars', '/tCompetitionAudit/tCompetition_update', 3, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (296, 'educational', '0', '[0],', '教务', 'fa-bars', '#', 4, 1, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (297, '/coursePackage', 'educational', '[0],[educational],', '课包管理', 'fa-bars', '/coursePackage/openCoursePackageListPage', 3, 2, 1, NULL, 1, NULL);
@@ -638,14 +638,14 @@
 INSERT INTO `sys_menu` VALUES (604, '/tQuestion/off', '/tQuestion', '[0],[system],[/tQuestion],', '下架', 'fa-bars', '/tQuestion/off', 7, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (605, 'mgr_detail', 'mgr', '[0],[system],[mgr],', '查看详情', '', 'mgr_detail', 5, 3, 0, NULL, 1, 1);
 INSERT INTO `sys_menu` VALUES (606, '/tAgree/QrCodeDescription', 'system', '[0],[system],', '二维码注意事项配置', 'fa-bars', '/tAgree/QrCodeDescription', 7, 2, 1, NULL, 1, NULL);
-INSERT INTO `sys_menu` VALUES (607, 'worldCup', '0', '[0],', '社区世界杯', 'fa-bars', '#', 8, 1, 1, NULL, 1, NULL);
+INSERT INTO `sys_menu` VALUES (607, 'worldCup', '0', '[0],', '赛事', 'fa-bars', '#', 8, 1, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (608, 'referee', 'worldCup', '[0],[worldCup],', '裁判管理', 'fa-bars', '/referee', 3, 2, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (609, 'openAddReferee', 'referee', '[0],[worldCup],[referee],', '添加', 'fa-bars', '/referee/openAddReferee', 1, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (610, 'openEditReferee', 'referee', '[0],[worldCup],[referee],', '编辑', 'fa-bars', '/referee/openEditReferee', 2, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (611, 'delReferee', 'referee', '[0],[worldCup],[referee],', '删除', 'fa-bars', '/referee/delReferee', 3, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (612, 'offShelf', 'referee', '[0],[worldCup],[referee],', '冻结', 'fa-bars', '/referee/offShelf', 4, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (613, 'onShelf', 'referee', '[0],[worldCup],[referee],', '解冻', 'fa-bars', '/referee/onShelf', 5, 3, 0, NULL, 1, NULL);
-INSERT INTO `sys_menu` VALUES (614, 'worldCupList', 'worldCup', '[0],[worldCup],', '比赛管理', 'fa-bars', '/worldCup', 1, 2, 1, NULL, 1, NULL);
+INSERT INTO `sys_menu` VALUES (614, 'worldCupList', 'worldCup', '[0],[worldCup],', '赛事管理', 'fa-bars', '/worldCup', 1, 2, 1, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (615, 'openAddWorldCup', 'worldCupList', '[0],[worldCup],[worldCupList],', '添加', 'fa-bars', '/worldCup/openAddWorldCup', 1, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (616, 'openEditWorldCup', 'worldCupList', '[0],[worldCup],[worldCupList],', '编辑', 'fa-bars', '/worldCup/openEditWorldCup', 2, 3, 0, NULL, 1, NULL);
 INSERT INTO `sys_menu` VALUES (617, 'cancelWorldCup', 'worldCupList', '[0],[worldCup],[worldCupList],', '取消', 'fa-bars', '/worldCup/cancelWorldCup', 3, 3, 0, NULL, 1, NULL);

--
Gitblit v1.7.1