From ac3e9a7f0b21fb630049f9e191bd760eefd21467 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期六, 16 八月 2025 18:04:38 +0800
Subject: [PATCH] 管理后台会员管理

---
 cloud-server-account/src/main/java/com/dsh/account/entity/VipPayment.java                                |   15 
 cloud-server-activity/src/main/java/com/dsh/activity/model/GrantCoupon.java                              |   40 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TVipController.java    |  450 +++++++
 cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_add.html                             |  170 ++
 cloud-server-account/src/main/java/com/dsh/account/vo/CouponVipResp.java                                 |   43 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipResp.java               |   43 
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java               |    3 
 cloud-server-account/src/main/java/com/dsh/account/entity/Vip.java                                       |  109 +
 cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/TCoupon.html                             |   66 +
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TVipServiceImpl.java      |   33 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponStore.java                 |   52 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Vip.java                         |  107 +
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCouponController.java |   18 
 cloud-server-account/src/main/java/com/dsh/account/vo/VipPaymentVO.java                                  |   25 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Protocol.java                    |    2 
 cloud-server-management/src/main/resources/mapper/VipMapper.xml                                          |   16 
 cloud-server-activity/src/main/java/com/dsh/activity/service/VipDetailService.java                       |   18 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/Coupon.java              |   11 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/CouponClient.java              |   11 
 cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java                     |  122 +
 cloud-server-account/src/main/java/com/dsh/account/service/impl/VipPaymentServiceImpl.java               |   84 +
 cloud-server-activity/src/main/java/com/dsh/activity/service/impl/VipDetailServiceImpl.java              |   19 
 cloud-server-activity/src/main/java/com/dsh/activity/mapper/VipDetailMapper.java                         |   23 
 cloud-server-management/src/main/java/com/dsh/course/mapper/TVipMapper.java                              |   26 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipVo.java                 |   43 
 cloud-server-management/src/main/webapp/static/modular/system/vip/TCoupon.js                             |  335 +++++
 cloud-server-activity/src/main/java/com/dsh/activity/entity/UserCoupon.java                              |    5 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java                    |   56 
 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TicketDetailVO.java      |   15 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip.html                                 |   52 
 cloud-server-management/src/main/webapp/static/modular/system/vip/vip.js                                 |  557 ++++++++
 cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java             |  114 +
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TicketVipResp.java               |   22 
 cloud-server-account/src/main/java/com/dsh/account/vo/TicketVipResp.java                                 |   22 
 cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/GrantCoupon.java           |   42 
 cloud-server-activity/src/main/java/com/dsh/activity/entity/VipDetail.java                               |   65 +
 cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java                |   88 +
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IVipService.java               |   18 
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/CouponListOfSearch.java           |    1 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_edit.html                            |  191 +++
 cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/UserConponClient.java            |    5 
 cloud-server-account/src/main/java/com/dsh/account/vo/ConponJsonRuleModel.java                           |   25 
 cloud-server-management/src/main/webapp/static/modular/system/vip/vip_info.js                            |  278 ++++
 cloud-server-account/src/main/java/com/dsh/account/service/IVipPaymentService.java                       |    2 
 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/ConponJsonRuleModel.java         |   25 
 cloud-server-account/src/main/java/com/dsh/account/feignclient/other/VipClient.java                      |   28 
 cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_detail.html                          |  184 ++
 47 files changed, 3,608 insertions(+), 71 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 57ad510..c3f74a1 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
@@ -3,16 +3,13 @@
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.api.R;
 import com.dsh.account.dto.BindDto;
 import com.dsh.account.dto.IntroduceUserQuery;
 import com.dsh.account.dto.SelectDto;
 import com.dsh.account.dto.UpdateInfoDto;
-import com.dsh.account.entity.IntroduceUser;
-import com.dsh.account.entity.TAppGift;
-import com.dsh.account.entity.TAppUser;
-import com.dsh.account.entity.TCourseInfoRecord;
-import com.dsh.account.entity.TStudent;
-import com.dsh.account.entity.UserIntegralChanges;
+import com.dsh.account.entity.*;
+import com.dsh.account.feignclient.other.VipClient;
 import com.dsh.account.model.AddAppUserVo;
 import com.dsh.account.model.AdvertisementChangeStateDTO;
 import com.dsh.account.model.AppUserByNameAndPhoneDTO;
@@ -34,6 +31,7 @@
 import com.dsh.account.util.TokenUtil;
 import com.dsh.account.util.ToolUtil;
 import com.dsh.account.util.wx.WxV3PayConfig;
+import com.dsh.account.vo.VipPaymentVO;
 import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -68,6 +66,8 @@
 
     @Autowired
     private TAppUserService appUserService;
+    @Autowired
+    private VipClient vipClient;
 
     @Autowired
     private PayMoneyUtil payMoneyUtil;
@@ -438,9 +438,10 @@
     @ApiOperation(value = "购买年度会员", tags = {"APP-成为会员"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "支付方式(1=微信,2=支付宝)", name = "payType", dataType = "int", required = true),
+            @ApiImplicitParam(value = "会员卡id", name = "id", dataType = "int", required = true),
             @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
     })
-    public ResultUtil addVipPayment(Integer payType) {
+    public ResultUtil addVipPayment(Integer payType,Integer id) {
         if (ToolUtil.isEmpty(payType)) {
             return ResultUtil.paranErr("payType");
         }
@@ -449,59 +450,84 @@
             if (null == uid) {
                 return ResultUtil.tokenErr();
             }
-            return vipPaymentService.addVipPayment(uid, payType);
+            return vipPaymentService.addVipPayment(uid, payType, id);
         } catch (Exception e) {
             e.printStackTrace();
             return ResultUtil.runErr();
         }
     }
-
-
-    /**
-     * 购买年度会员支付微信回调V3版本回调
-     *
-     * @param request
-     * @param response
-     */
     @ResponseBody
-    @PostMapping("/base/appUser/addVipPaymentWeChatCallback1")
-    public void addVipPaymentWeChatCallback1(HttpServletRequest request, HttpServletResponse response) {
-        try {
-            System.err.println("微信回调");
-            System.err.println("请求" + request);
-            BufferedReader reader = request.getReader();
-            String string1 = reader.toString();
-            System.err.println("请求reader" + string1);
-            StringBuilder requestBody = new StringBuilder();
-            String line;
-            while ((line = reader.readLine()) != null) {
-                requestBody.append(line);
-            }
-            System.err.println("全部请求体" + requestBody);
-            JSONObject jsonObject = JSONObject.parseObject(requestBody.toString());
-            JSONObject resource = jsonObject.getJSONObject("resource");
+    @PostMapping("/api/appUser/vipPayment")
+    @ApiOperation(value = "页面数据展示", tags = {"APP-成为会员"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResultUtil<VipPaymentVO> vipPayment() {
 
-            AesUtil aesUtil = new AesUtil(WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
-            String decryptedData = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes(StandardCharsets.UTF_8),
-                    resource.getString("ciphertext"));
-            System.err.println("微信解密的字符串信息" + decryptedData);
-            JSONObject jsonInfo = (JSONObject) JSONObject.parse(decryptedData);
-            String out_trade_no = jsonInfo.getString("out_trade_no");
-            String transaction_id = jsonInfo.getString("transaction_id");
-            String trade_state = jsonInfo.getString("trade_state");
-            if (trade_state.equals("SUCCESS")) {
-                ResultUtil resultUtil = vipPaymentService.addVipPaymentCallback(out_trade_no, transaction_id);
-                if (resultUtil.getCode() == 200) {
-                    PrintWriter out = response.getWriter();
-                    out.write("SUCCESS");
-                    out.flush();
-                    out.close();
-                }
+        try {
+            Integer uid = tokenUtil.getUserIdFormRedis();
+            if (null == uid) {
+                return ResultUtil.tokenErr();
             }
+            TAppUser appUser = appUserService.getById(uid);
+            VipPaymentVO res = new VipPaymentVO();
+            res.setHeadImg(appUser.getHeadImg());
+            res.setName(appUser.getName());
+            res.setIsVip(appUser.getIsVip());
+            List<Vip> vips = vipClient.listAll();
+            res.setVipList(vips);
         } catch (Exception e) {
             e.printStackTrace();
+            return ResultUtil.runErr();
         }
+        return ResultUtil.success();
     }
+//
+//    /**
+//     * 购买年度会员支付微信回调V3版本回调
+//     *
+//     * @param request
+//     * @param response
+//     */
+//    @ResponseBody
+//    @PostMapping("/base/appUser/addVipPaymentWeChatCallback1")
+//    public void addVipPaymentWeChatCallback1(HttpServletRequest request, HttpServletResponse response) {
+//        try {
+//            System.err.println("微信回调");
+//            System.err.println("请求" + request);
+//            BufferedReader reader = request.getReader();
+//            String string1 = reader.toString();
+//            System.err.println("请求reader" + string1);
+//            StringBuilder requestBody = new StringBuilder();
+//            String line;
+//            while ((line = reader.readLine()) != null) {
+//                requestBody.append(line);
+//            }
+//            System.err.println("全部请求体" + requestBody);
+//            JSONObject jsonObject = JSONObject.parseObject(requestBody.toString());
+//            JSONObject resource = jsonObject.getJSONObject("resource");
+//
+//            AesUtil aesUtil = new AesUtil(WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
+//            String decryptedData = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes(StandardCharsets.UTF_8),
+//                    resource.getString("ciphertext"));
+//            System.err.println("微信解密的字符串信息" + decryptedData);
+//            JSONObject jsonInfo = (JSONObject) JSONObject.parse(decryptedData);
+//            String out_trade_no = jsonInfo.getString("out_trade_no");
+//            String transaction_id = jsonInfo.getString("transaction_id");
+//            String trade_state = jsonInfo.getString("trade_state");
+//            if (trade_state.equals("SUCCESS")) {
+//                ResultUtil resultUtil = vipPaymentService.addVipPaymentCallback(out_trade_no, transaction_id);
+//                if (resultUtil.getCode() == 200) {
+//                    PrintWriter out = response.getWriter();
+//                    out.write("SUCCESS");
+//                    out.flush();
+//                    out.close();
+//                }
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
     /**
      * 购买年度会员支付微信回调
      *
diff --git a/cloud-server-account/src/main/java/com/dsh/account/entity/Vip.java b/cloud-server-account/src/main/java/com/dsh/account/entity/Vip.java
new file mode 100644
index 0000000..80ca82e
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/entity/Vip.java
@@ -0,0 +1,109 @@
+package com.dsh.account.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.dsh.account.vo.CouponVipResp;
+import com.dsh.account.vo.TicketVipResp;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 会员管理
+ */
+@TableName("t_vip")
+@Data
+@ApiModel(description = "会员")
+public class Vip {
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @TableField("id")
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    /**
+     * 会员名称
+     */
+    @TableField("vipName")
+    @ApiModelProperty(value = "会员名称")
+    private String vipName;
+
+    /**
+     * 会员时长类型 1天 2月 3年
+     */
+    @TableField("timeType")
+    @ApiModelProperty(value = "会员时长类型 1天 2月 3年")
+    private Integer timeType;
+
+    /**
+     * 会员时长
+     */
+    @TableField("time")
+    @ApiModelProperty(value = "会员时长数量 对应会员时长类型 x天 x月 x年")
+    private Integer time;
+
+    /**
+     * 会员价格
+     */
+    @TableField("price")
+    @ApiModelProperty(value = "会员价格")
+    private BigDecimal price;
+
+    /**
+     * 状态 1上架2下架
+     */
+    @TableField("status")
+    @ApiModelProperty(value = "状态 1上架2下架")
+    private Integer status;
+
+    /**
+     * 添加时间
+     */
+    @TableField("insertTime")
+    @ApiModelProperty(value = "添加时间")
+    private Date insertTime;
+    /**
+     * 添加时间
+     */
+    @TableField("couponJson")
+    @ApiModelProperty(value = "优惠券json[{\n" +
+            "\t\"id\": \"1\",\n" +
+            "\t\"value\": \"1\"\n" +
+            "}, {\n" +
+            "\t\"id\": \"2\",\n" +
+            "\t\"value\": \"1\"\n" +
+            "}\n" +
+            "}]")
+    private String couponJson;
+    /**
+     * 添加时间
+     */
+    @TableField("ticketJson")
+    @ApiModelProperty(value = "门票json门票json[{\n" +
+            "\t\"name\": \"门票名称\",\n" +
+            "\t\"time\": \"1\",\n" +
+            "\"count\": \"1\",\n" +
+            "}]")
+    private String ticketJson;
+
+    /**
+     * 会员优惠券权益
+     */
+    @TableField(exist = false)
+    @ApiModelProperty(value = "会员优惠券权益")
+    private List<CouponVipResp> couponList;
+    /**
+     * 会员门票权益
+     */
+    @TableField(exist = false)
+    @ApiModelProperty(value = "会员门票权益")
+    private List<TicketVipResp> ticketList;
+}
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 6e633c7..c2257b7 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
@@ -64,11 +64,26 @@
     @TableField("state")
     private Integer state;
     /**
+     * 会员id
+     */
+    @TableField("vipId")
+    private Integer vipId;
+    /**
      * 添加时间
      */
     @TableField("insertTime")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date insertTime;
+    /**
+     * 购买会员时 获得的门票权益
+     */
+    @TableField("ticketJson")
+    private String ticketJson;
+    /**
+     * 购买会员时 获得的优惠券权益
+     */
+    @TableField("couponJson")
+    private String couponJson;
 
 
     public static String CODE() {
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/UserConponClient.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/UserConponClient.java
index 44f1a3a..6bc4e53 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/UserConponClient.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/UserConponClient.java
@@ -1,6 +1,7 @@
 package com.dsh.account.feignclient.activity;
 
 import com.dsh.account.feignclient.activity.model.CommodityRequest;
+import com.dsh.account.feignclient.activity.model.GrantCoupon;
 import com.dsh.account.feignclient.activity.model.UserCoupon;
 import com.dsh.account.model.dto.Coupon;
 import com.dsh.account.model.vo.sourceDetail.CouponStuAvailableVo;
@@ -43,4 +44,8 @@
 
     @PostMapping("/userCoupon/queryCounts1")
     Integer queryCounts1(@RequestBody List<Integer> queryIds);
+
+    @PostMapping("/userCoupon/grantCoupon")
+    void grantCoupon(@RequestBody GrantCoupon grantCoupon);
+
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/GrantCoupon.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/GrantCoupon.java
new file mode 100644
index 0000000..80b6784
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/GrantCoupon.java
@@ -0,0 +1,42 @@
+package com.dsh.account.feignclient.activity.model;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 开会员送券
+ * </p>
+ *
+ * @author jqs
+ * @since 2023-06-29
+ */
+@Data
+public class GrantCoupon {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 优惠券json
+     */
+    private String couponJson;
+    /**
+     * 优惠券json
+     */
+    private String ticketJson;
+    /**
+     * 用户id
+     */
+    private Integer userId;
+    /**
+     * vipId
+     */
+    private Integer vipId;
+    /**
+     * 会员支付记录id
+     */
+    private Integer vipPaymentId;
+
+
+}
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/VipClient.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/VipClient.java
new file mode 100644
index 0000000..c85a845
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/VipClient.java
@@ -0,0 +1,28 @@
+package com.dsh.account.feignclient.other;
+
+import com.dsh.account.entity.OperatorUser;
+import com.dsh.account.entity.User;
+import com.dsh.account.entity.Vip;
+import com.dsh.account.feignclient.competition.model.BillingDataRequestVo;
+import com.dsh.account.feignclient.other.model.SiteBooking;
+import com.dsh.account.model.RequestOfTypeVo;
+import com.dsh.account.model.vo.exploreDetail.SiteVo;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+import java.util.Map;
+
+
+@FeignClient("mb-cloud-other")
+public interface VipClient {
+
+
+    @PostMapping("/vip/listAll")
+    List<Vip> listAll();
+    @PostMapping("/vip/getVipByIds")
+    List<Vip> getVipByIds(@RequestBody String ids);
+
+}
diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/IVipPaymentService.java b/cloud-server-account/src/main/java/com/dsh/account/service/IVipPaymentService.java
index 31bea44..2a30fac 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/service/IVipPaymentService.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/service/IVipPaymentService.java
@@ -22,7 +22,7 @@
      * @return
      * @throws Exception
      */
-    ResultUtil addVipPayment(Integer uid, Integer payType) throws Exception;
+    ResultUtil addVipPayment(Integer uid, Integer payType,Integer vipId) throws Exception;
 
 
     /**
diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/VipPaymentServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/VipPaymentServiceImpl.java
index 53dfda7..55b5a3d 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/VipPaymentServiceImpl.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/VipPaymentServiceImpl.java
@@ -1,26 +1,37 @@
 package com.dsh.account.service.impl;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dsh.account.entity.TAppUser;
+import com.dsh.account.entity.Vip;
 import com.dsh.account.entity.VipPayment;
 import com.dsh.account.feignclient.activity.UserConponClient;
+import com.dsh.account.feignclient.activity.UserCouponPaymentClient;
+import com.dsh.account.feignclient.activity.model.GrantCoupon;
+import com.dsh.account.feignclient.other.VipClient;
 import com.dsh.account.mapper.VipPaymentMapper;
 import com.dsh.account.model.IncomeQuery;
 import com.dsh.account.service.IVipPaymentService;
 import com.dsh.account.service.TAppUserService;
+import com.dsh.account.util.DateUtil;
 import com.dsh.account.util.PayMoneyUtil;
 import com.dsh.account.util.RedisUtil;
 import com.dsh.account.util.ResultUtil;
 import com.dsh.account.util.wx.WxV3PayConfig;
+import com.dsh.account.vo.CouponVipResp;
+import org.apache.commons.lang.time.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
@@ -44,6 +55,9 @@
 
     @Autowired
     private RedisUtil redisUtil;
+    @Autowired
+    private VipClient vipClient;
+
 
 
     /**
@@ -54,14 +68,26 @@
      * @throws Exception
      */
     @Override
-    public ResultUtil addVipPayment(Integer uid, Integer payType) throws Exception {
+    public ResultUtil addVipPayment(Integer uid, Integer payType, Integer vipId) throws Exception {
+        if (vipId == null) {
+            return ResultUtil.error("会员id未传参");
+        }
+        List<Vip> vipByIds = vipClient.getVipByIds(vipId.toString());
+        if (vipByIds.isEmpty()) {
+            return ResultUtil.error("会员不存在");
+        }
+        Vip vip = vipByIds.get(0);
         VipPayment vipPayment = new VipPayment();
         vipPayment.setCode(VipPayment.CODE());
-        vipPayment.setAmount(0.01D);
+        vipPayment.setAmount(vip.getPrice().doubleValue());
         vipPayment.setAppUserId(uid);
         vipPayment.setInsertTime(new Date());
         vipPayment.setPayStatus(1);
         vipPayment.setState(1);
+        vipPayment.setPayType(payType);
+        vipPayment.setVipId(vip.getId());
+        vipPayment.setCouponJson(vip.getCouponJson());
+        vipPayment.setTicketJson(vip.getTicketJson());
         this.baseMapper.insert(vipPayment);
         if (payType == 1) {//微信
             return weixinpay(vipPayment);
@@ -82,7 +108,7 @@
      */
     public ResultUtil weixinpay(VipPayment vipPayment) throws Exception {
         String code = vipPayment.getCode();
-        ResultUtil weixinpay = payMoneyUtil.weixinpay("购买年度会员", "", code, vipPayment.getAmount().toString(),
+        ResultUtil weixinpay = payMoneyUtil.weixinpay("购买会员", "", code, vipPayment.getAmount().toString(),
                 "/base/appUser/addVipPaymentWeChatCallback", "APP", "");
 //        ResultUtil weixinpay = payMoneyUtil.weixinpayV3(WxV3PayConfig.smidVx,"购买年度会员",
 //                code,"/base/appUser/addVipPaymentWeChatCallback1",
@@ -98,14 +124,15 @@
      * @throws Exception
      */
     private String smid = "2088330203191220";//平台支付宝商户号
+
     public ResultUtil alipay(VipPayment vipPayment) throws Exception {
         String code = vipPayment.getCode();
         String amount = vipPayment.getAmount().toString();
         ResultUtil alipay = payMoneyUtil.alipay
-                (smid,"购买年度会员", "购买年度会员",
+                (smid, "购买年度会员", "购买年度会员",
                         vipPayment.getAppUserId() + "",
                         code, vipPayment.getAmount().toString(),
-                "/base/appUser/addVipPaymentAliCallback");
+                        "/base/appUser/addVipPaymentAliCallback");
         if (alipay.getCode() == 200) {
             new Thread(new Runnable() {
                 @Override
@@ -210,12 +237,51 @@
         if (null == vipEndTime) {
             vipEndTime = new Date();
         }
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(vipEndTime);
-        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 1);
+        // 将Date类型 转化为LocalDateTime
+        LocalDateTime localDateTime = LocalDateTime.ofInstant(vipEndTime.toInstant(), ZoneId.systemDefault());
+        List<Vip> vipByIds = vipClient.getVipByIds(vipPayment1.getVipId() + "");
+        if (vipByIds.isEmpty()) {
+            return ResultUtil.error("会员不存在");
+        }
+        Vip vip = vipByIds.get(0);
+        Integer time = vip.getTime();
+
+        // 根据time和时间类型 决定给会员加多少天
+        switch (vip.getTimeType()) {
+            case 1:
+                // 天
+                localDateTime.plusDays(time);
+                break;
+            case 2:
+                // 月
+                localDateTime.plusMonths(time);
+
+                break;
+            case 3:
+                // 年
+                localDateTime.plusYears(time);
+                break;
+        }
         appUser.setIsVip(1);
-        appUser.setVipEndTime(calendar.getTime());
+        Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
+        appUser.setVipEndTime(date);
         appUserService.updateById(appUser);
+        // 会员权益送券和门票
+        String couponJson = vipPayment1.getCouponJson();
+        GrantCoupon grantCoupon = new GrantCoupon();
+
+        if (StringUtils.hasLength(couponJson)) {
+            grantCoupon.setCouponJson(couponJson);
+            grantCoupon.setUserId(vipPayment1.getAppUserId());
+            grantCoupon.setVipPaymentId(vipPayment1.getId());
+        }
+        String ticketJson = vipPayment1.getTicketJson();
+        if (StringUtils.hasLength(ticketJson)) {
+            grantCoupon.setTicketJson(ticketJson);
+        }
+        // 远程调用 给用户送优惠券和门票
+        userConponClient.granCoupon(grantCoupon);
+
         // 注册会员送券 先判断是否有注册送券类型的优惠券 判断优惠券状态 审核是否通过 是否删除 是否在有效期内 是否领取数量达上限
         List<Long> longs = userConponClient.queryCouponByUser(appUser.getId());
         redisUtil.setStrValue("VIP_P_" + vipPayment1.getAppUserId(), JSON.toJSONString(longs), 3600);
diff --git a/cloud-server-account/src/main/java/com/dsh/account/vo/ConponJsonRuleModel.java b/cloud-server-account/src/main/java/com/dsh/account/vo/ConponJsonRuleModel.java
new file mode 100644
index 0000000..be45c01
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/vo/ConponJsonRuleModel.java
@@ -0,0 +1,25 @@
+package com.dsh.account.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+@Data
+public class ConponJsonRuleModel {
+    /**
+     * 条件金额
+     */
+    @ApiModelProperty("条件金额(例如 :满xx可用)")
+    String conditionalAmount;
+    /**
+     * 抵扣金额(代金券 取 该字段)
+     */
+    @ApiModelProperty("抵扣金额(代金券 取 该字段) 例如:¥ xxx")
+    String deductionAmount;
+    /**
+     * 体验券名称
+     */
+    @ApiModelProperty("体验券名称 ")
+    String experienceName;
+
+}
diff --git a/cloud-server-account/src/main/java/com/dsh/account/vo/CouponVipResp.java b/cloud-server-account/src/main/java/com/dsh/account/vo/CouponVipResp.java
new file mode 100644
index 0000000..964a9cf
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/vo/CouponVipResp.java
@@ -0,0 +1,43 @@
+package com.dsh.account.vo;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("会员权益优惠券列表")
+public class CouponVipResp {
+
+    @ApiModelProperty("优惠券id")
+    private Integer id;
+
+    @ApiModelProperty("优惠券名称")
+    private String name;
+
+    @ApiModelProperty("优惠券类型(1=满减券,2=代金券,3=体验券)")
+    private Integer type;
+
+    @ApiModelProperty("适用范围1全国通用 2指定城市可用 3指定门店可用")
+    private Integer useCondition;
+
+    @ApiModelProperty("适用范围名称")
+    private String available;
+
+    @ApiModelProperty("useCondition = 2,为地址字符串;useCondition = 3,为门店名称+地址字符串")
+    private String cityOrStore;
+
+    @ApiModelProperty("优惠券说明(使用说明)")
+    private String instructionsForUse;
+
+    @ApiModelProperty("金额条件封装")
+    private ConponJsonRuleModel ruleModel;
+
+    @ApiModelProperty("有效时间(2021-05-05)")
+    private String effectiveTime;
+    @ApiModelProperty("数量 张")
+    private Integer count;
+
+
+
+}
diff --git a/cloud-server-account/src/main/java/com/dsh/account/vo/TicketVipResp.java b/cloud-server-account/src/main/java/com/dsh/account/vo/TicketVipResp.java
new file mode 100644
index 0000000..b790117
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/vo/TicketVipResp.java
@@ -0,0 +1,22 @@
+package com.dsh.account.vo;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("会员权益门票列表")
+public class TicketVipResp {
+
+
+    @ApiModelProperty("门票名称")
+    private String name;
+
+    @ApiModelProperty("领取后x天有效")
+    private Integer time;
+
+    @ApiModelProperty("数量 张")
+    private Integer count;
+
+}
diff --git a/cloud-server-account/src/main/java/com/dsh/account/vo/VipPaymentVO.java b/cloud-server-account/src/main/java/com/dsh/account/vo/VipPaymentVO.java
new file mode 100644
index 0000000..f1b9917
--- /dev/null
+++ b/cloud-server-account/src/main/java/com/dsh/account/vo/VipPaymentVO.java
@@ -0,0 +1,25 @@
+package com.dsh.account.vo;
+
+import com.dsh.account.entity.Vip;
+import com.dsh.account.entity.VipPayment;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@ApiModel("购买会员页面数据返回VO")
+public class VipPaymentVO {
+
+    @ApiModelProperty(value = "头像")
+    private String headImg;
+    @ApiModelProperty(value = "用户名称")
+    private String name;
+    @ApiModelProperty(value = "当前是否会员 0否1是")
+    private Integer isVip;
+    @ApiModelProperty(value = "所有上架的会员卡")
+    private List<Vip> vipList;
+
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java
index 606f194..730d3b4 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/CouponController.java
@@ -189,6 +189,31 @@
             return null;
         }
     }
+
+    @ResponseBody
+    @PostMapping("/coupon/queryCouponAll")
+    public List<Coupon> queryCouponAll() {
+        try {
+
+            return couponService.lambdaQuery().eq(Coupon::getState,1)
+                    .eq(Coupon::getAuditStatus,2).list();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+    @ResponseBody
+    @PostMapping("/coupon/queryCouponList")
+    public List<Coupon> queryCouponList() {
+        try {
+
+            return couponService.lambdaQuery().ne(Coupon::getState,3)
+                    .eq(Coupon::getAuditStatus,2).list();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
     @ResponseBody
     @PostMapping("/coupon/queryUserCouponById")
     public Integer queryUserCouponById(@RequestBody Long id) {
@@ -416,6 +441,26 @@
                 int count = ucService.count(new LambdaQueryWrapper<UserCoupon>()
                         .eq(UserCoupon::getCouponId, o));
                 stringObjectMap.put("hasPickQty", count);
+            }
+        }
+        return mapList;
+    }
+    @ResponseBody
+    @PostMapping("/base/coupon/getCouponListAllOfSearch")
+    public List<Map<String, Object>> getCouponListAllOfSearch(@RequestBody CouponListOfSearch ofSearch) {
+        List<Map<String, Object>> mapList1 = couponService.queryCouponListOfSearch(ofSearch);
+
+        List<Map<String, Object>> mapList = new ArrayList<>();
+        if (ofSearch.getStoreIds() == null) {
+            ArrayList<Integer> list = new ArrayList<>();
+            ofSearch.setStoreIds(list);
+        }
+        mapList = mapList1;
+        if (mapList.size() > 0) {
+            for (Map<String, Object> stringObjectMap : mapList) {
+                Object startTime = stringObjectMap.get("startTime");
+                Object endTime = stringObjectMap.get("endTime");
+                stringObjectMap.put("timeValue", startTime + "至" + endTime);
             }
         }
         return mapList;
@@ -796,12 +841,23 @@
         List<CouponCity> list = cityService.list(new LambdaQueryWrapper<CouponCity>().eq(CouponCity::getCouponId, id));
         return list;
     }
+    @ResponseBody
+    @PostMapping("/base/coupon/queryAllCity")
+    public List<CouponCity> queryAllCity() {
+        List<CouponCity> list = cityService.list(new LambdaQueryWrapper<CouponCity>());
+        return list;
+    }
 
     @ResponseBody
     @PostMapping("/base/coupon/queryStore")
     public List<Integer> queryStore(@RequestBody Integer id) {
         return couStoreService.list(new LambdaQueryWrapper<CouponStore>().eq(CouponStore::getCouponId, id)).stream().map(CouponStore::getStoreId).collect(Collectors.toList());
     }
+    @ResponseBody
+    @PostMapping("/base/coupon/queryAllStore")
+    public List<CouponStore> queryAllStore() {
+        return couStoreService.list(new LambdaQueryWrapper<CouponStore>());
+    }
 
 
     @PostMapping("/base/coupon/listRecord")
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 a6a67dc..82b47e7 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
@@ -623,6 +623,8 @@
 
     @Autowired
     private UserCouponService userCouponService;
+    @Autowired
+    private VipDetailService vipDetailService;
 
     @PostMapping("/base/pointMerchars/getGoodDetails")
     public ProductDetailsVo getGoodDetailsWithId(@RequestBody ProductDetailRequest detailRequest) {
@@ -1039,6 +1041,28 @@
             detailsVo.setDetailsResponses(responses);
         }
 
+        // 2.0新增会员权益赠送门票
+        List<VipDetail> list = vipDetailService.lambdaQuery()
+                .eq(VipDetail::getAppUserId, appUserId).eq(VipDetail::getType, 2).list();
+        for (VipDetail vipDetail : list) {
+                ExchangeDetailsResponse detailsResponse = new ExchangeDetailsResponse();
+                // 添加-用于区分会员权益门票
+                detailsResponse.setDetailsId(Long.valueOf("-"+vipDetail.getId()));
+                detailsResponse.setGoodName(vipDetail.getTicketName());
+                detailsResponse.setStartTime(simpleDateFormat.format(vipDetail.getStartTime()));
+                detailsResponse.setEndTime(simpleDateFormat.format(vipDetail.getEndTime()));
+
+
+                detailsResponse.setUseStatus(vipDetail.getStatus());
+                detailsResponse.setGoodType(3);
+                // 表明是会员赠送的门票
+                detailsResponse.setExchangeType(3);
+                // 全国通用
+            detailsResponse.setRid(Collections.singletonList(0));
+            detailsResponse.setSid(Collections.singletonList(0));
+
+                responses.add(detailsResponse);
+            }
         if (userCoupons.size() > 0) {
             for (UserCoupon userCoupon : userCoupons) {
 
@@ -1083,9 +1107,95 @@
     public PointDetailsVo getSpecificsOfGoods(@RequestBody Long speMercharsId) {
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
         PointDetailsVo detailsVo = new PointDetailsVo();
+
+        if (speMercharsId.toString().contains("-1")){
+            // 会员门票
+            VipDetail vipDetail = vipDetailService.getById(Math.abs(speMercharsId));
+            if (vipDetail.getType()==1){
+                Coupon coupon = iCouponService.getById(vipDetail.getCouponId());
+                detailsVo.setDetailsId(Long.valueOf(coupon.getId()));
+                List<String> list3 = new ArrayList<>();
+                list3.add(ToolUtil.isEmpty(coupon.getCover()) ? "" : coupon.getCover());
+                if (ToolUtil.isNotEmpty(coupon.getProductImages())) {
+                    list3.addAll(Arrays.asList(StrUtils.splitStr2StrArr(coupon.getProductImages(), ",")));
+                }
+                detailsVo.setPics(list3);
+                Collections.sort(detailsVo.getPics(), (s1, s2) -> {
+                    if (s1.equals(coupon.getCover())) {
+                        return -1; // s1排在前面
+                    } else if (s2.equals(coupon.getCover())) {
+                        return 1; // s2排在前面
+                    } else {
+                        return 0; // 保持原顺序
+                    }
+                });
+                detailsVo.setGoodName(coupon.getName());
+                detailsVo.setExchangeType(coupon.getRedemptionMethod());
+                if (coupon.getRedemptionMethod() == 1) {
+                    detailsVo.setIntegral(coupon.getIntegral().intValue());
+                } else {
+                    detailsVo.setIntegral(coupon.getIntegral().intValue());
+                    detailsVo.setCash(coupon.getCash());
+                }
+                if (coupon.getUseScope() == 1) {
+                    detailsVo.setExchangeAddrType(1);
+                    detailsVo.setBelongs("全国通用");
+                } else if (coupon.getUseScope() == 2) {
+                    detailsVo.setExchangeAddrType(2);
+                    List<CouponCity> list = ccityService.list(new LambdaQueryWrapper<CouponCity>()
+                            .eq(CouponCity::getCouponId, coupon.getId()));
+                    if (list.size() > 0) {
+                        detailsVo.setBelongs(list.get(0).getProvince() + "|" + list.get(0).getCity() + "用户可用");
+                    }
+                } else {
+                    detailsVo.setExchangeAddrType(3);
+                    List<CouponStore> list = cstoreService.list(new QueryWrapper<CouponStore>()
+                            .eq("couponId", coupon.getId()));
+                    StoreDetailOfCourse courseOfStore = stoClient.getCourseOfStore(list.get(0).getStoreId());
+                    detailsVo.setBelongs(courseOfStore.getStoreName() + "可用");
+                }
+                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+                detailsVo.setStartTime(format.format(coupon.getStartTime()));
+                detailsVo.setEndTime(format.format(coupon.getEndTime()));
+
+                detailsVo.setContents(coupon.getIllustrate());
+                detailsVo.setGoodType(4);
+            }else{
+
+                // 门票
+                detailsVo.setDetailsId(Long.valueOf("-"+vipDetail.getId()));
+                detailsVo.setGoodName(vipDetail.getTicketName());
+                switch (vipDetail.getStatus()){
+                    case 1:
+                        detailsVo.setUseType(2);
+                        break;
+                    case 2:
+                        detailsVo.setUseType(1);
+                        break;
+                    case 3:
+                        detailsVo.setUseType(3);
+                        break;
+                }
+                detailsVo.setStartTime(simpleDateFormat.format(vipDetail.getStartTime()));
+                detailsVo.setEndTime(simpleDateFormat.format(vipDetail.getEndTime()));
+                detailsVo.setOrderTime(simpleDateFormat.format(vipDetail.getInsertTime()));
+                if (vipDetail.getUseTime()!=null){
+                    detailsVo.setWriteOffTime(simpleDateFormat.format(vipDetail.getUseTime()));
+                }
+                if (vipDetail.getUseStoreId()!=null){
+                    StoreDetailOfCourse courseOfStore = stoClient.getCourseOfStore(vipDetail.getUseStoreId());
+                    detailsVo.setWriteOffName(courseOfStore.getStoreName());
+                }
+
+                detailsVo.setBelongs("全国通用");
+                detailsVo.setGoodType(3);
+                detailsVo.setCardType(1);
+                detailsVo.setExchangeAddrType(1);
+            }
+            detailsVo.setDetailsId(Long.valueOf("-"+vipDetail.getId()));
+            return detailsVo;
+        }
         UserPointsMerchandise byId = upmseService.getById(speMercharsId);
-
-
         if (ToolUtil.isNotEmpty(byId)) {
             List<PointsMerchandiseStore> stores = storeService.list(new QueryWrapper<PointsMerchandiseStore>().eq("pointsMerchandiseId", byId.getPointsMerchandiseId()));
 
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 38aea5c..3b49b8b 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
@@ -1,21 +1,24 @@
 package com.dsh.activity.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.dsh.activity.entity.Coupon;
-import com.dsh.activity.entity.CouponStore;
-import com.dsh.activity.entity.TStudent;
-import com.dsh.activity.entity.UserCoupon;
+import com.dsh.activity.entity.*;
 import com.dsh.activity.feignclient.account.AppUserClient;
 import com.dsh.activity.feignclient.account.StudentClient;
 import com.dsh.activity.feignclient.account.model.AppUser;
 import com.dsh.activity.feignclient.model.CouponStuAvailableVo;
 import com.dsh.activity.feignclient.model.QueryUserCouponByIdAndUserId;
 import com.dsh.activity.model.CouponListVo;
+import com.dsh.activity.model.GrantCoupon;
 import com.dsh.activity.model.SendCouponReq;
 import com.dsh.activity.service.CouponStoreService;
 import com.dsh.activity.service.ICouponService;
 import com.dsh.activity.service.UserCouponService;
+import com.dsh.activity.service.VipDetailService;
+import com.dsh.activity.util.DateUtil;
 import com.dsh.activity.util.ResultUtil;
 import com.dsh.activity.util.TokenUtil;
 import io.swagger.annotations.Api;
@@ -23,6 +26,7 @@
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -56,6 +60,8 @@
 
     @Resource
     private StudentClient studentClient;
+    @Autowired
+    private VipDetailService vipDetailService;
 
 
 
@@ -315,8 +321,78 @@
     @PostMapping("/userCoupon/queryCounts1")
     public Integer queryCounts1(@RequestBody List<Integer> queryIds) {
         return userCouponService.count(new QueryWrapper<UserCoupon>().eq("couponId", queryIds.get(0)).eq("userId", queryIds.get(1)));
-
-
     }
 
+    // 开通会员后 赠送优惠券和门票
+    @ResponseBody
+    @PostMapping("/userCoupon/grantCoupon")
+    public void grantCoupon(@RequestBody GrantCoupon grantCoupon) {
+        String couponJson = grantCoupon.getCouponJson();
+        if (StringUtils.hasLength(couponJson)) {
+
+            // 赠送优惠券
+            JSONArray objects = JSON.parseArray(couponJson);
+            for (Object object : objects) {
+                JSONObject jsonObject = (JSONObject) object;
+                // 优惠券id
+                String id = jsonObject.getString("id");
+                // 优惠券数量
+                String value = jsonObject.getString("value");
+                for (Integer i = 0; i < Integer.valueOf(value); i++) {
+                    UserCoupon userCoupon = new UserCoupon();
+                    userCoupon.setCouponId(Integer.valueOf(id));
+                    userCoupon.setUserId(grantCoupon.getUserId());
+                    userCoupon.setStatus(1);
+                    userCoupon.setVerificationUserId(null);
+                    userCoupon.setVerificationTime(null);
+                    userCoupon.setInsertTime(new Date());
+                    userCoupon.setIsVipGrant(1);
+                    userCouponService.save(userCoupon);
+                    // 生成对应的权益明细记录
+                    VipDetail vipDetail = new VipDetail();
+                    vipDetail.setAppUserId(grantCoupon.getUserId());
+                    vipDetail.setStatus(1);
+                    vipDetail.setInsertTime(new Date());
+                    vipDetail.setVipId(grantCoupon.getVipId());
+                    vipDetail.setType(1);
+                    vipDetail.setVipPaymentId(grantCoupon.getVipPaymentId());
+                    vipDetail.setCouponId(Integer.valueOf(id));
+                    vipDetail.setUserCouponId(userCoupon.getId());
+                    vipDetailService.save(vipDetail);
+                }
+            }
+        }
+        String ticketJson = grantCoupon.getTicketJson();
+        if (StringUtils.hasLength(ticketJson)) {
+            // 赠送优惠券
+            JSONArray objects = JSON.parseArray(ticketJson);
+            for (Object object : objects) {
+                JSONObject jsonObject = (JSONObject) object;
+                // 门票名称
+                String name = jsonObject.getString("name");
+                // 领取后x天有效
+                String time = jsonObject.getString("time");
+                Integer days = Integer.valueOf(time);
+                // 可用次数
+                String count = jsonObject.getString("count");
+                for (Integer i = 0; i < Integer.valueOf(count); i++) {
+                    // 生成对应的权益明细记录
+                    VipDetail vipDetail = new VipDetail();
+                    vipDetail.setTicketName(name);
+                    vipDetail.setStartTime(new Date());
+                    Date date = new Date();
+                    // 加X天
+                    Date tomorrow = new Date(date.getTime() + 24 * 60 * 60 * 1000L * days);
+                    vipDetail.setEndTime(tomorrow);
+                    vipDetail.setAppUserId(grantCoupon.getUserId());
+                    vipDetail.setStatus(1);
+                    vipDetail.setInsertTime(new Date());
+                    vipDetail.setVipId(grantCoupon.getVipPaymentId());
+                    vipDetail.setType(2);
+                    vipDetail.setVipPaymentId(grantCoupon.getVipPaymentId());
+                    vipDetailService.save(vipDetail);
+                }
+            }
+        }
+    }
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserCoupon.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserCoupon.java
index 1871a88..349a798 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserCoupon.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/UserCoupon.java
@@ -66,6 +66,11 @@
     @TableField("insertTime")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date insertTime;
+    /**
+     * 是否为会员赠送 0否1是
+     */
+    @TableField("isVipGrant")
+    private Integer isVipGrant;
 
 
     @Override
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/VipDetail.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/VipDetail.java
new file mode 100644
index 0000000..40ca4ab
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/VipDetail.java
@@ -0,0 +1,65 @@
+package com.dsh.activity.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.Date;
+
+@Data
+@ApiModel(value = "VipDetail", description = "会员权益明细")
+public class VipDetail {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.NONE)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户id")
+    private Integer appUserId;
+
+    @ApiModelProperty(value = "使用状态 1待使用 2已使用 3已过期")
+    private Integer status;
+
+    @ApiModelProperty(value = "获取时间")
+    private Date insertTime;
+
+    @ApiModelProperty(value = "会员id")
+    private Integer vipId;
+
+    @ApiModelProperty(value = "会员权益类型 1优惠券 2门票")
+    private Integer type;
+
+    @ApiModelProperty(value = "会员支付记录id")
+    private Integer vipPaymentId;
+
+    @ApiModelProperty(value = "优惠券id")
+    private Integer couponId;
+
+    @ApiModelProperty(value = "门票名称")
+    private String ticketName;
+
+    @ApiModelProperty(value = "开始时间")
+    private Date startTime;
+
+    @ApiModelProperty(value = "结束时间")
+    private Date endTime;
+
+    @ApiModelProperty(value = "可用次数")
+    private Integer useCount;
+
+    @ApiModelProperty(value = "使用门店id")
+    private Integer useStoreId;
+
+    @ApiModelProperty(value = "使用场地id")
+    private Integer useSiteId;
+
+    @ApiModelProperty(value = "使用时间")
+    private Date useTime;
+
+    @ApiModelProperty(value = "运营商id")
+    private Integer operatorId;
+
+    @ApiModelProperty(value = "用户优惠券id")
+    private Long userCouponId;
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/CouponListOfSearch.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/CouponListOfSearch.java
index fc2a538..2ca1c03 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/CouponListOfSearch.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/CouponListOfSearch.java
@@ -31,4 +31,5 @@
     private List<Integer> storeIds;
     // 运营商使用
     private List<TOperatorCity> operatorCities;
+
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java
index 854d597..2cd3d2f 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java
@@ -19,7 +19,7 @@
     @ApiModelProperty(value = "商品名称")
     private String goodName;
 
-    @ApiModelProperty(value = "适用状态(1已使用 2未使用)")
+    @ApiModelProperty(value = "适用状态(1已使用 2未使用 3过期)")
     private Integer useType;
 
     @ApiModelProperty(value = "有效期开始时间")
@@ -59,6 +59,7 @@
     @ApiModelProperty(value = "兑换方式(1=积分,2=积分+现金)")
     private Integer exchangeType;
 
+    @ApiModelProperty("1日卡 2月卡 3季卡 4年卡")
     private Integer cardType;
 
     @ApiModelProperty(value = "使用范围")
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/mapper/VipDetailMapper.java b/cloud-server-activity/src/main/java/com/dsh/activity/mapper/VipDetailMapper.java
new file mode 100644
index 0000000..78b5492
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/mapper/VipDetailMapper.java
@@ -0,0 +1,23 @@
+package com.dsh.activity.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.activity.entity.Coupon;
+import com.dsh.activity.entity.VipDetail;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 优惠券 Mapper 接口
+ * </p>
+ *
+ * @author jqs
+ * @since 2023-06-29
+ */
+public interface VipDetailMapper extends BaseMapper<VipDetail> {
+
+
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/model/GrantCoupon.java b/cloud-server-activity/src/main/java/com/dsh/activity/model/GrantCoupon.java
new file mode 100644
index 0000000..4f62ec2
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/model/GrantCoupon.java
@@ -0,0 +1,40 @@
+package com.dsh.activity.model;
+
+import lombok.Data;
+
+/**
+ * <p>
+ * 开会员送券
+ * </p>
+ *
+ * @author jqs
+ * @since 2023-06-29
+ */
+@Data
+public class GrantCoupon {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 优惠券json
+     */
+    private String couponJson;
+    /**
+     * 优惠券json
+     */
+    private String ticketJson;
+    /**
+     * 用户id
+     */
+    private Integer userId;
+    /**
+     * vipId
+     */
+    private Integer vipId;
+    /**
+     * 会员支付记录id
+     */
+    private Integer vipPaymentId;
+
+
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/VipDetailService.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/VipDetailService.java
new file mode 100644
index 0000000..cacddd0
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/VipDetailService.java
@@ -0,0 +1,18 @@
+package com.dsh.activity.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dsh.activity.entity.VipDetail;
+import com.dsh.activity.model.IntroduceUser;
+import com.dsh.activity.model.IntroduceUserQuery;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 介绍有礼-用户参与 服务类
+ * </p>
+ */
+public interface VipDetailService extends IService<VipDetail> {
+
+
+}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/VipDetailServiceImpl.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/VipDetailServiceImpl.java
new file mode 100644
index 0000000..1ed491d
--- /dev/null
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/VipDetailServiceImpl.java
@@ -0,0 +1,19 @@
+package com.dsh.activity.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dsh.activity.entity.THuiminAgreement;
+import com.dsh.activity.entity.VipDetail;
+import com.dsh.activity.mapper.HuiminAgreementMapper;
+import com.dsh.activity.mapper.VipDetailMapper;
+import com.dsh.activity.service.HuiminAgreementService;
+import com.dsh.activity.service.VipDetailService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/7/11 17:31
+ */
+@Service
+public class VipDetailServiceImpl extends ServiceImpl<VipDetailMapper, VipDetail> implements VipDetailService {
+
+}
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 0490859..dea9322 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
@@ -3,6 +3,7 @@
 
 import com.dsh.course.feignClient.activity.model.*;
 import com.dsh.guns.modular.system.model.CouponDataVo;
+import com.dsh.guns.modular.system.model.CouponStore;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -16,6 +17,8 @@
 
     @PostMapping("/base/coupon/queryCouponListSearch")
     List<Map<String,Object>> getCouponListOfSearch(@RequestBody CouponListOfSearch ofSearch);
+    @PostMapping("/base/coupon/getCouponListAllOfSearch")
+    List<Map<String,Object>> getCouponListAllOfSearch(@RequestBody CouponListOfSearch ofSearch);
 
 
     @PostMapping("/base/coupon/queryCouponListSearch1")
@@ -31,6 +34,10 @@
 
     @PostMapping("/coupon/queryCouponById")
     Coupon queryCouponById(@RequestBody Integer id);
+    @PostMapping("/coupon/queryCouponAll")
+    List<Coupon> queryCouponAll();
+    @PostMapping("/coupon/queryCouponList")
+    List<Coupon> queryCouponList();
 
 
     @PostMapping("/base/coupon/updateCouponExamine")
@@ -41,8 +48,12 @@
 
     @PostMapping("/base/coupon/queryCity")
     List<CouponCity> queryCity(Integer id);
+    @PostMapping("/base/coupon/queryAllCity")
+    List<CouponCity> queryAllCity();
     @PostMapping("/base/coupon/queryStore")
     List<Integer> queryStore(Integer id);
+    @PostMapping("/base/coupon/queryAllStore")
+    List<CouponStore> queryAllStore();
 
     @PostMapping("/base/coupon/listRecord")
     List<Map<String,Object>> listRecord(CouponRecordQuery ofSearch);
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/Coupon.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/Coupon.java
index d299f01..6572476 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/Coupon.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/Coupon.java
@@ -85,6 +85,10 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date endTime;
     /**
+     * 有效期
+     */
+    private String timeValue;
+    /**
      * 使用范围(1=全国,2=指定城市,3=指定门店)
      */
     private Integer useScope;
@@ -128,5 +132,12 @@
      * 城市管理者id
      */
     private Integer cityManagerId;
+    /**
+     * 数量
+     */
+    private Integer count;
+    private String useScopeValue;
+    private String typeValue;
+    private String userPopulationValue;
 
 }
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TicketDetailVO.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TicketDetailVO.java
new file mode 100644
index 0000000..44e12ae
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/TicketDetailVO.java
@@ -0,0 +1,15 @@
+package com.dsh.course.feignClient.activity.model;
+
+import lombok.Data;
+
+@Data
+public class TicketDetailVO {
+
+    // 门票名称
+    private String name;
+    // 领取后多少天有效
+    private Integer time;
+    // 门票数量
+    private Integer count;
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/course/mapper/TVipMapper.java b/cloud-server-management/src/main/java/com/dsh/course/mapper/TVipMapper.java
new file mode 100644
index 0000000..e9748b6
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/course/mapper/TVipMapper.java
@@ -0,0 +1,26 @@
+package com.dsh.course.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.guns.modular.system.model.TStoreOtherConfig;
+import com.dsh.guns.modular.system.model.Vip;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author administrator
+ * @since 2023-09-19
+ */
+public interface TVipMapper extends BaseMapper<Vip> {
+
+    List<Map<String, Object>> listOfPage(@Param("vipName")String name, @Param("status")Integer status, @Param("page")Page<Map<String, Object>> page);
+
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCouponController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCouponController.java
index 1498593..bc07141 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCouponController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TCouponController.java
@@ -303,9 +303,21 @@
 
         return couponListOfSearch;
     }
-    /**
-     * 根据运营商ID 获取运营商管理的省市
-     */
+    @RequestMapping(value = "/listSelect")
+    @ResponseBody
+    public Object listOfDatas(String name, Integer type, Integer status, Integer state) {
+        Page<Map<String, Object>> page = new PageFactory<Map<String, Object>>().defaultPage();
+        CouponListOfSearch ofSearch = new CouponListOfSearch();
+        ofSearch.setPage(page);
+        ofSearch.setName(name);
+        ofSearch.setType(type);
+        ofSearch.setStatus(status);
+        ofSearch.setState(state);
+        List<Map<String, Object>> couponListOfSearch = client.getCouponListAllOfSearch(ofSearch);
+        return couponListOfSearch;
+    }
+
+
 
     /**
      * 获取 优惠券管理
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TVipController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TVipController.java
new file mode 100644
index 0000000..08f1f7d
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TVipController.java
@@ -0,0 +1,450 @@
+package com.dsh.guns.modular.system.controller.code;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.course.feignClient.activity.CouponClient;
+import com.dsh.course.feignClient.activity.model.Coupon;
+import com.dsh.course.feignClient.activity.model.CouponCity;
+import com.dsh.course.feignClient.activity.model.TicketDetailVO;
+import com.dsh.guns.core.base.controller.BaseController;
+import com.dsh.guns.core.common.constant.factory.PageFactory;
+import com.dsh.guns.modular.system.model.*;
+import com.dsh.guns.modular.system.service.IStoreService;
+import com.dsh.guns.modular.system.service.IVipService;
+import com.dsh.guns.modular.system.util.ResultUtil;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author zhibing.pu
+ * @Date 2023/8/1 14:02
+ */
+@Controller
+@RequestMapping("/vip")
+public class TVipController extends BaseController {
+
+    @Autowired
+    private IVipService vipService;
+    @Autowired
+    private CouponClient couponClient;
+    @Autowired
+    private IStoreService storeService;
+    private String PREFIX = "/system/vip/";
+
+
+    /**
+     * 跳转到优惠券管理首页
+     */
+    @RequestMapping("")
+    public String index(Model model) {
+
+        return PREFIX + "vip.html";
+    }
+    @RequestMapping("/add")
+    public String add(Model model) {
+
+        return PREFIX + "vip_add.html";
+    }
+    @RequestMapping("/edit/{id}")
+    public String edit(@PathVariable("id")Integer id,Model model) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        Vip vip = vipService.getById(id);
+        model.addAttribute("vip",vip);
+        if (vip.getCouponJson() != null && !vip.getCouponJson().isEmpty()){
+            String couponJson = vip.getCouponJson();
+            // 转化为jsonArray
+            JSONArray couponJsonArray = JSONArray.parseArray(couponJson);
+            List<Integer> couponIds = new ArrayList<>();
+            Map<Integer, Integer> integerIntegerHashMap = new HashMap<>();
+            // 收集里面得id
+            for (Object o : couponJsonArray) {
+                JSONObject couponJsonObject = (JSONObject) o;
+                Integer couponId = couponJsonObject.getInteger("id");
+                Integer count = couponJsonObject.getInteger("value");
+                integerIntegerHashMap.put(couponId, count);
+                couponIds.add(couponId);
+            }
+            List<Coupon> coupons = couponClient.queryCouponList();
+
+            if (!couponIds.isEmpty()){
+                coupons = coupons.stream().filter(coupon -> couponIds.contains(coupon.getId())).collect(Collectors.toList());
+                for (Coupon coupon : coupons) {
+                    Date startTime = coupon.getStartTime();
+                    Date endTime = coupon.getEndTime();
+                    coupon.setTimeValue(simpleDateFormat.format(startTime) + "至" + simpleDateFormat.format(endTime));
+                    Integer orDefault = integerIntegerHashMap.getOrDefault(coupon.getId(), 0);
+                    coupon.setCount(orDefault);
+                    switch (coupon.getUseScope()){
+                        case 1:
+                            coupon.setUseScopeValue("全国");
+                            break;
+                        case 2:
+                            coupon.setUseScopeValue("指定城市");
+                            break;
+                        case 3:
+                            coupon.setUseScopeValue("指定门店");
+                            break;
+                    }
+                    switch (coupon.getType()){
+                        case 1:
+                            coupon.setTypeValue("满减券");
+                            break;
+                        case 2:
+                            coupon.setTypeValue("代金券");
+                            break;
+                        case 3:
+                            coupon.setTypeValue("体验券");
+                            break;
+                    }
+                    switch (coupon.getUserPopulation()){
+                        case 1:
+                            coupon.setUserPopulationValue("全部用户");
+                            break;
+                        case 2:
+                            coupon.setUserPopulationValue("会员");
+                            break;
+                        case 3:
+                            coupon.setUserPopulationValue("已有学员用户");
+                            break;
+                    }
+                }
+                model.addAttribute("couponList", coupons);
+            }else{
+                model.addAttribute("couponList", new ArrayList<Coupon>());
+            }
+        }
+        if (vip.getTicketJson() != null && !vip.getTicketJson().isEmpty()){
+            String ticketJson = vip.getTicketJson();
+            // 转化为jsonArray
+            JSONArray ticketJsonArray = JSONArray.parseArray(ticketJson);
+            // 收集里面得id
+            List<TicketDetailVO> ticketDetailVOS = new ArrayList<>();
+
+            for (Object o : ticketJsonArray) {
+                JSONObject couponJsonObject = (JSONObject) o;
+                TicketDetailVO ticketDetailVO = new TicketDetailVO();
+                ticketDetailVO.setName(couponJsonObject.getString("name"));
+                ticketDetailVO.setTime(couponJsonObject.getInteger("time"));
+                ticketDetailVO.setCount(couponJsonObject.getInteger("count"));
+                ticketDetailVOS.add(ticketDetailVO);
+            }
+            model.addAttribute("ticketList", ticketDetailVOS);
+        }
+        return PREFIX + "vip_edit.html";
+    }
+
+    public static void main(String[] args) {
+        String temp = "[{\"id\":\"36\",\"value\":\"1\"}]";
+        JSONArray couponJsonArray = JSONArray.parseArray(temp);
+        for (Object o : couponJsonArray) {
+            JSONObject couponJsonObject = (JSONObject) o;
+            Integer couponId = couponJsonObject.getInteger("id");
+        }
+    }
+    @RequestMapping("/detail/{id}")
+    public String detail(@PathVariable("id")Integer id, Model model) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        Vip vip = vipService.getById(id);
+        model.addAttribute("vip",vip);
+        if (vip.getCouponJson() != null && !vip.getCouponJson().isEmpty()){
+            String couponJson = vip.getCouponJson();
+            // 转化为jsonArray
+            JSONArray couponJsonArray = JSONArray.parseArray(couponJson);
+            List<Integer> couponIds = new ArrayList<>();
+            Map<Integer, Integer> integerIntegerHashMap = new HashMap<>();
+            // 收集里面得id
+            for (Object o : couponJsonArray) {
+                JSONObject couponJsonObject = (JSONObject) o;
+                Integer couponId = couponJsonObject.getInteger("id");
+                Integer count = couponJsonObject.getInteger("value");
+                integerIntegerHashMap.put(couponId, count);
+                couponIds.add(couponId);
+            }
+            List<Coupon> coupons = couponClient.queryCouponList();
+
+            if (!couponIds.isEmpty()){
+                coupons = coupons.stream().filter(coupon -> couponIds.contains(coupon.getId())).collect(Collectors.toList());
+                for (Coupon coupon : coupons) {
+                    Date startTime = coupon.getStartTime();
+                    Date endTime = coupon.getEndTime();
+                    coupon.setTimeValue(simpleDateFormat.format(startTime) + "至" + simpleDateFormat.format(endTime));
+                    Integer orDefault = integerIntegerHashMap.getOrDefault(coupon.getId(), 0);
+                    coupon.setCount(orDefault);
+                    switch (coupon.getUseScope()){
+                        case 1:
+                            coupon.setUseScopeValue("全国");
+                            break;
+                        case 2:
+                            coupon.setUseScopeValue("指定城市");
+                            break;
+                        case 3:
+                            coupon.setUseScopeValue("指定门店");
+                            break;
+                    }
+                    switch (coupon.getType()){
+                        case 1:
+                            coupon.setTypeValue("满减券");
+                            break;
+                        case 2:
+                            coupon.setTypeValue("代金券");
+                            break;
+                        case 3:
+                            coupon.setTypeValue("体验券");
+                            break;
+                    }
+                    switch (coupon.getUserPopulation()){
+                        case 1:
+                            coupon.setUserPopulationValue("全部用户");
+                            break;
+                        case 2:
+                            coupon.setUserPopulationValue("会员");
+                            break;
+                        case 3:
+                            coupon.setUserPopulationValue("已有学员用户");
+                            break;
+                    }
+                }
+                model.addAttribute("couponList", coupons);
+            }else{
+                model.addAttribute("couponList", new ArrayList<Coupon>());
+            }
+        }
+        if (vip.getTicketJson() != null && !vip.getTicketJson().isEmpty()){
+            String ticketJson = vip.getTicketJson();
+            // 转化为jsonArray
+            JSONArray ticketJsonArray = JSONArray.parseArray(ticketJson);
+            // 收集里面得id
+            List<TicketDetailVO> ticketDetailVOS = new ArrayList<>();
+
+            for (Object o : ticketJsonArray) {
+                JSONObject couponJsonObject = (JSONObject) o;
+                TicketDetailVO ticketDetailVO = new TicketDetailVO();
+                ticketDetailVO.setName(couponJsonObject.getString("name"));
+                ticketDetailVO.setTime(couponJsonObject.getInteger("time"));
+                ticketDetailVO.setCount(couponJsonObject.getInteger("count"));
+                ticketDetailVOS.add(ticketDetailVO);
+            }
+            model.addAttribute("ticketList", ticketDetailVOS);
+        }
+
+        return PREFIX + "vip_detail.html";
+    }
+    /**
+     * 跳转到门店管理列表页
+     */
+    @RequestMapping("/couponList")
+    public String couponList(Model model) {
+        return PREFIX + "TCoupon.html";
+    }
+    @RequestMapping(value = "/addVipInfo")
+    @ResponseBody
+    public ResultUtil addVipInfo(String vipName, Integer time, Integer timeType, String price,String couponJson, String ticketJson) {
+        Vip vip = new Vip();
+        vip.setVipName(vipName);
+        vip.setTimeType(timeType);
+        vip.setTime(time);
+        vip.setPrice(new BigDecimal(price));
+        vip.setStatus(1);
+        vip.setInsertTime(new Date());
+        vip.setCouponJson(couponJson);
+        vip.setTicketJson(ticketJson);
+        vipService.save(vip);
+        return ResultUtil.success();
+    }
+    @RequestMapping(value = "/editVipInfo")
+    @ResponseBody
+    public ResultUtil addVipInfo(Integer id,String vipName, Integer time, Integer timeType, String price,String couponJson, String ticketJson) {
+        Vip vip = vipService.getById(id);
+        vip.setVipName(vipName);
+        vip.setTimeType(timeType);
+        vip.setTime(time);
+        vip.setPrice(new BigDecimal(price));
+        vip.setInsertTime(new Date());
+        if (couponJson==null){
+            couponJson = "";
+        }
+        vip.setCouponJson(couponJson);
+        if (ticketJson==null){
+            ticketJson = "";
+        }
+        vip.setTicketJson(ticketJson);
+        vipService.updateById(vip);
+        return ResultUtil.success();
+    }
+    @RequestMapping(value = "/offShelf")
+    @ResponseBody
+    public ResultUtil offShelf(Integer id) {
+        Vip vip = vipService.getById(id);
+        vip.setStatus(2);
+        vipService.updateById(vip);
+        return ResultUtil.success();
+    }
+    @RequestMapping(value = "/onShelf")
+    @ResponseBody
+    public ResultUtil onShelf(Integer id) {
+        Vip vip = vipService.getById(id);
+        vip.setStatus(1);
+        vipService.updateById(vip);
+        return ResultUtil.success();
+    }
+    /**
+     * 获取 会员卡列表
+     */
+    @RequestMapping(value = "/list")
+    @ResponseBody
+    public List<Map<String, Object>> list(String vipName, Integer status) {
+        Page<Map<String, Object>> page = new PageFactory<Map<String, Object>>().defaultPage();
+        List<Map<String, Object>> maps = vipService.listOfPage(vipName, status, page);
+        for (Map<String, Object> map : maps) {
+            Object timeType = map.get("timeType");
+            Object time = map.get("time");
+            Integer timeTypeValue = Integer.valueOf(timeType.toString());
+            Integer timeValue = Integer.valueOf(time.toString());
+            switch (timeTypeValue) {
+                case 1:
+                    map.put("time",timeValue+"天");
+                    break;
+                case 2:
+                    map.put("time",timeValue+"月");
+                    break;
+                case 3:
+                    map.put("time",timeValue+"年");
+                    break;
+            }
+        }
+        return maps;
+    }
+
+    // APP查询所有上架的会员卡
+    @ResponseBody
+    @PostMapping("/listAll")
+    public List<Vip> listAll() {
+        List<Vip> list = vipService.lambdaQuery().eq(Vip::getStatus, 1).list();
+        List<Coupon> coupons = couponClient.queryCouponAll();
+        List<CouponCity> couponCityList = couponClient.queryAllCity();
+        List<CouponStore> storeList = couponClient.queryAllStore();
+        List<TStore> shopList = storeService.list();
+        // 封装会员权益
+        for (Vip vip : list) {
+            List<CouponVipResp> couponVipRespList = new ArrayList<>();
+            List<TicketVipResp> ticketVipRespList = new ArrayList<>();
+            String couponJson = vip.getCouponJson();
+            JSONArray couponJsonArray = JSONArray.parseArray(couponJson);
+            for (Object o : couponJsonArray) {
+                JSONObject couponJsonObject = (JSONObject) o;
+                // 优惠券id
+                Integer id = Integer.valueOf(couponJsonObject.getString("id"));
+                // 优惠券数量
+                Integer value = Integer.valueOf(couponJsonObject.getString("value"));
+                Coupon coupon = coupons.stream().filter(e -> e.getId().equals(id)).findFirst().orElse(new Coupon());
+                CouponVipResp couponVipResp = new CouponVipResp();
+                couponVipResp.setId(coupon.getId());
+                couponVipResp.setName(coupon.getName());
+                couponVipResp.setType(coupon.getType());
+                couponVipResp.setUseCondition(coupon.getUseScope());
+                couponVipResp.setCount(value);
+                switch (coupon.getUseScope()) {
+                    case 1:
+                        couponVipResp.setAvailable("全国通用");
+                        break;
+                    case 2:
+                        couponVipResp.setAvailable("指定城市可用");
+                        List<CouponCity> couponId = couponCityList.stream().filter(e -> e.getCouponId().equals(id))
+                                .collect(Collectors.toList());
+                        StringBuilder stringBuilder = new StringBuilder();
+                        for (CouponCity couponCity : couponId) {
+                            stringBuilder.append(couponCity.getCity());
+                        }
+                        couponVipResp.setCityOrStore(String.valueOf(stringBuilder));
+                        break;
+                    case 3:
+                        couponVipResp.setAvailable("指定门店可用");
+                        // 门店ids
+                        List<Integer> storeIds = storeList.stream().filter(e -> e.getCouponId().equals(id))
+                                .map(CouponStore::getStoreId).collect(Collectors.toList());
+                        StringBuilder storeNames = new StringBuilder("");
+
+                        if (!storeIds.isEmpty()) {
+                            List<TStore> stores = shopList.stream().filter(e -> storeIds.contains(e.getId())).collect(Collectors.toList());
+                            for (TStore store : stores) {
+                                storeNames.append(store.getName()).append(",");
+                            }
+                            // 去除最后一位
+                            StringBuilder res = storeNames.deleteCharAt(storeNames.length() - 1);
+                            couponVipResp.setCityOrStore(res.toString());
+                        } else {
+                            couponVipResp.setCityOrStore("无可用门店");
+                        }
+                        break;
+                    default:
+                        break;
+                }
+                couponVipResp.setInstructionsForUse(coupon.getIllustrate());
+                ConponJsonRuleModel ruleModel = new ConponJsonRuleModel();
+                JSONObject jsonObject = JSON.parseObject(coupon.getContent());
+                switch (coupon.getType()) {
+                    case 1:
+//                            满减券
+                        Double num1 = jsonObject.getDouble("conditionalAmount");
+                        Double num2 = jsonObject.getDouble("deductionAmount");
+                        ruleModel.setConditionalAmount("满" + num1 + "可用");
+                        ruleModel.setDeductionAmount("¥ " + num2);
+                        ruleModel.setExperienceName("");
+                        break;
+                    case 2:
+//                            代金券
+                        Double jsonObjectDouble = jsonObject.getDouble("conditionalAmount");
+                        ruleModel.setConditionalAmount("");
+                        ruleModel.setDeductionAmount("¥ " + jsonObjectDouble);
+                        ruleModel.setExperienceName("");
+                        break;
+                    case 3:
+//                            体验券
+                        ruleModel.setConditionalAmount("");
+                        ruleModel.setDeductionAmount("");
+                        ruleModel.setExperienceName(jsonObject.getString("experienceName"));
+                        break;
+                    default:
+                        break;
+                }
+                couponVipResp.setRuleModel(ruleModel);
+
+                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+                couponVipResp.setEffectiveTime(simpleDateFormat.format(coupon.getEndTime()));
+                couponVipRespList.add(couponVipResp);
+            }
+            vip.setCouponList(couponVipRespList);
+            String ticketJson = vip.getTicketJson();
+            JSONArray ticketJsonArray = JSONArray.parseArray(ticketJson);
+            for (Object o : ticketJsonArray) {
+                JSONObject ticketJsonObject = (JSONObject) o;
+                TicketVipResp ticketVipResp = new TicketVipResp();
+                ticketVipResp.setName(ticketJsonObject.getString("name"));
+                ticketVipResp.setTime(ticketJsonObject.getInteger("time"));
+                ticketVipResp.setCount(ticketJsonObject.getInteger("count"));
+                ticketVipRespList.add(ticketVipResp);
+            }
+            vip.setTicketList(ticketVipRespList);
+        }
+        return list;
+    }
+
+    @ResponseBody
+    @PostMapping("/getVipByIds")
+    public List<Vip> getVipByIds(@RequestBody String ids) {
+        List<Vip> list = vipService.lambdaQuery().in(Vip::getId, Arrays.asList(ids.split(","))).list();
+        return list;
+    }
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/ConponJsonRuleModel.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/ConponJsonRuleModel.java
new file mode 100644
index 0000000..28f609a
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/ConponJsonRuleModel.java
@@ -0,0 +1,25 @@
+package com.dsh.guns.modular.system.model;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+@Data
+public class ConponJsonRuleModel {
+    /**
+     * 条件金额
+     */
+    @ApiModelProperty("条件金额(例如 :满xx可用)")
+    String conditionalAmount;
+    /**
+     * 抵扣金额(代金券 取 该字段)
+     */
+    @ApiModelProperty("抵扣金额(代金券 取 该字段) 例如:¥ xxx")
+    String deductionAmount;
+    /**
+     * 体验券名称
+     */
+    @ApiModelProperty("体验券名称 ")
+    String experienceName;
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponStore.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponStore.java
new file mode 100644
index 0000000..d48bb12
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponStore.java
@@ -0,0 +1,52 @@
+package com.dsh.guns.modular.system.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 优惠券使用门店关系数据
+ * </p>
+ *
+ * @author jqs
+ * @since 2023-07-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_coupon_store")
+public class CouponStore extends Model<CouponStore> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+    /**
+     * 优惠券id
+     */
+    @TableField("couponId")
+    private Integer couponId;
+    /**
+     * 门店id
+     */
+    @TableField("storeId")
+    private Integer storeId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipResp.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipResp.java
new file mode 100644
index 0000000..8df54b9
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipResp.java
@@ -0,0 +1,43 @@
+package com.dsh.guns.modular.system.model;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("会员权益优惠券列表")
+public class CouponVipResp {
+
+    @ApiModelProperty("优惠券id")
+    private Integer id;
+
+    @ApiModelProperty("优惠券名称")
+    private String name;
+
+    @ApiModelProperty("优惠券类型(1=满减券,2=代金券,3=体验券)")
+    private Integer type;
+
+    @ApiModelProperty("适用范围1全国通用 2指定城市可用 3指定门店可用")
+    private Integer useCondition;
+
+    @ApiModelProperty("适用范围名称")
+    private String available;
+
+    @ApiModelProperty("useCondition = 2,为地址字符串;useCondition = 3,为门店名称+地址字符串")
+    private String cityOrStore;
+
+    @ApiModelProperty("优惠券说明(使用说明)")
+    private String instructionsForUse;
+
+    @ApiModelProperty("金额条件封装")
+    private ConponJsonRuleModel ruleModel;
+
+    @ApiModelProperty("有效时间(2021-05-05)")
+    private String effectiveTime;
+    @ApiModelProperty("数量 张")
+    private Integer count;
+
+
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipVo.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipVo.java
new file mode 100644
index 0000000..935194e
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/CouponVipVo.java
@@ -0,0 +1,43 @@
+package com.dsh.guns.modular.system.model;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel("会员权益优惠券返回VO")
+public class CouponVipVo {
+    /**
+     * 用户类型1=城市管理者 2=平台管理者
+     */
+    @ApiModelProperty("优惠券id")
+    Integer userType;
+    /**
+     * 城市管理者id
+     */
+    Integer cityManagerId;
+    /**
+     * 券名称
+     */
+    String couponName;
+    /**
+     * 优惠券类型
+     */
+    Integer prescription;
+    /**
+     * 条件金额
+     */
+    BigDecimal condition;
+    /**
+     * 减去金额
+     */
+    BigDecimal subtraction;
+    /**
+     * 折扣金额
+     */
+    BigDecimal discount;
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Protocol.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Protocol.java
index 42ee1e2..bec2a40 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Protocol.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Protocol.java
@@ -21,7 +21,7 @@
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
     /**
-     * 数据类型(1=用户协议,2=隐私协议,3=运动安全公告书)
+     * 数据类型(1=用户协议,2=隐私协议,3=运动安全公告书 6)
      */
     @TableField("type")
     private Integer type;
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TicketVipResp.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TicketVipResp.java
new file mode 100644
index 0000000..2b13ef1
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TicketVipResp.java
@@ -0,0 +1,22 @@
+package com.dsh.guns.modular.system.model;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("会员权益门票列表")
+public class TicketVipResp {
+
+
+    @ApiModelProperty("门票名称")
+    private String name;
+
+    @ApiModelProperty("领取后x天有效")
+    private Integer time;
+
+    @ApiModelProperty("数量 张")
+    private Integer count;
+
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Vip.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Vip.java
new file mode 100644
index 0000000..181d445
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/Vip.java
@@ -0,0 +1,107 @@
+package com.dsh.guns.modular.system.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 会员管理
+ */
+@TableName("t_vip")
+@Data
+@ApiModel(description = "会员")
+public class Vip {
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @TableField("id")
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    /**
+     * 会员名称
+     */
+    @TableField("vipName")
+    @ApiModelProperty(value = "会员名称")
+    private String vipName;
+
+    /**
+     * 会员时长类型 1天 2月 3年
+     */
+    @TableField("timeType")
+    @ApiModelProperty(value = "会员时长类型 1天 2月 3年")
+    private Integer timeType;
+
+    /**
+     * 会员时长
+     */
+    @TableField("time")
+    @ApiModelProperty(value = "会员时长")
+    private Integer time;
+
+    /**
+     * 会员价格
+     */
+    @TableField("price")
+    @ApiModelProperty(value = "会员价格")
+    private BigDecimal price;
+
+    /**
+     * 状态 1上架2下架
+     */
+    @TableField("status")
+    @ApiModelProperty(value = "状态 1上架2下架")
+    private Integer status;
+
+    /**
+     * 添加时间
+     */
+    @TableField("insertTime")
+    @ApiModelProperty(value = "添加时间")
+    private Date insertTime;
+    /**
+     * 添加时间
+     */
+    @TableField("couponJson")
+    @ApiModelProperty(value = "优惠券json[{\n" +
+            "\t\"id\": \"1\",\n" +
+            "\t\"value\": \"1\"\n" +
+            "}, {\n" +
+            "\t\"id\": \"2\",\n" +
+            "\t\"value\": \"1\"\n" +
+            "}\n" +
+            "}]")
+    private String couponJson;
+    /**
+     * 添加时间
+     */
+    @TableField("ticketJson")
+    @ApiModelProperty(value = "门票json门票json[{\n" +
+            "\t\"name\": \"门票名称\",\n" +
+            "\t\"time\": \"1\",\n" +
+            "\"count\": \"1\",\n" +
+            "}]")
+    private String ticketJson;
+
+    /**
+     * 会员优惠券权益
+     */
+    @TableField(exist = false)
+    @ApiModelProperty(value = "会员优惠券权益")
+    private List<CouponVipResp> couponList;
+    /**
+     * 会员门票权益
+     */
+    @TableField(exist = false)
+    @ApiModelProperty(value = "会员门票权益")
+    private List<TicketVipResp> ticketList;
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IVipService.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IVipService.java
new file mode 100644
index 0000000..1ded3ba
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IVipService.java
@@ -0,0 +1,18 @@
+package com.dsh.guns.modular.system.service;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dsh.guns.modular.system.model.Protocol;
+import com.dsh.guns.modular.system.model.Vip;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/6/14 15:04
+ */
+public interface IVipService extends IService<Vip> {
+    List<Map<String, Object>> listOfPage(String vipName, Integer status, Page<Map<String, Object>> page);
+}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TVipServiceImpl.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TVipServiceImpl.java
new file mode 100644
index 0000000..2297e6c
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TVipServiceImpl.java
@@ -0,0 +1,33 @@
+package com.dsh.guns.modular.system.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dsh.course.mapper.TOperatorAuthMapper;
+import com.dsh.course.mapper.TVipMapper;
+import com.dsh.guns.modular.system.model.OperatorAuthAlipay;
+import com.dsh.guns.modular.system.model.Vip;
+import com.dsh.guns.modular.system.service.IOperatorAuthService;
+import com.dsh.guns.modular.system.service.IVipService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author administrator
+ * @since 2023-09-19
+ */
+@Service
+public class TVipServiceImpl extends ServiceImpl<TVipMapper, Vip> implements IVipService {
+
+
+    @Override
+    public List<Map<String, Object>> listOfPage(String vipName, Integer status, Page<Map<String, Object>> page) {
+        return this.baseMapper.listOfPage(vipName, status, page);
+    }
+}
diff --git a/cloud-server-management/src/main/resources/mapper/VipMapper.xml b/cloud-server-management/src/main/resources/mapper/VipMapper.xml
new file mode 100644
index 0000000..56e172d
--- /dev/null
+++ b/cloud-server-management/src/main/resources/mapper/VipMapper.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dsh.course.mapper.TVipMapper">
+
+
+    <select id="listOfPage" resultType="java.util.Map">
+        select * from t_vip
+        where 1=1
+        <if test="vipName != null and vipName != ''">
+            and vipName like concat('%',#{vipName},'%')
+        </if>
+        <if test="status != null">
+            and status = #{status}
+        </if>
+    </select>
+</mapper>
\ No newline at end of file
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/TCoupon.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/TCoupon.html
new file mode 100644
index 0000000..a8e81d3
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/TCoupon.html
@@ -0,0 +1,66 @@
+@layout("/common/_container.html"){
+<div class="row">
+    <div class="col-sm-12">
+        <div class="ibox float-e-margins">
+            <div class="ibox-title">
+                <h5>选择</h5>
+            </div>
+            <div class="ibox-content">
+                <div class="row row-lg">
+                    <div class="col-sm-12">
+                        <div class="row">
+                            <div class="col-sm-3">
+                                <#NameCon id="name" name="优惠券名称" />
+                            </div>
+                            <div class="col-sm-3">
+                                <#SelectCon id="type" name="优惠券类型" >
+                                <option value="">全部</option>
+                                <option value="1">满减券</option>
+                                <option value="2">折扣券</option>
+                                <option value="3">体验券</option>
+                            </#SelectCon>
+                        </div>
+                        <div class="col-sm-3">
+                                <#SelectCon id="status" name="活动状态" >
+                                <option value="">全部</option>
+                                <option value="1">未开始</option>
+                                <option value="2">已开始</option>
+                                <option value="3">已结束</option>
+                            </#SelectCon>
+                        </div>
+
+            </div>
+                    <div class="col-sm-3">
+                <#SelectCon id="state" name="可售状态" >
+                <option value="">全部</option>
+                <option value="1">已上架</option>
+                <option value="2">已下架</option>
+                </#SelectCon>
+                        </div>
+        <div class="col-sm-3">
+            <#button name="搜索" icon="fa-search" clickFun="TCoupon.search()"/>
+            <#button name="重置" icon="fa-trash" clickFun="TCoupon.resetSearch()"/>
+        </div>
+                        </div>
+
+                        <#table id="TCouponTable"/>
+        <div style="margin-left: 30%">
+            <button type="button" class="btn btn-info button-margin" onclick="TCoupon.storeOfClosePage()"
+                    id="closePage" style="width: 30%;height: 40px;background: #0d8ddb;color: white;border: none;">
+                <i class="fa fa-check"></i>&nbsp;关闭
+            </button>
+
+            <button type="button" class="btn btn-info button-margin" onclick="TCoupon.saveSelectStores()"
+                    id="submit" style="margin-left: 5%;width: 30%;height: 40px;background: #0d8ddb;color: white;border: none;">
+                <i class="fa fa-check"></i>&nbsp;保存
+            </button>
+        </div>
+                    </div>
+                </div>
+            </div>
+
+        </div>
+    </div>
+</div>
+<script src="${ctxPath}/modular/system/vip/TCoupon.js"></script>
+@}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip.html
new file mode 100644
index 0000000..58ffe1b
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip.html
@@ -0,0 +1,52 @@
+@layout("/common/_container.html"){
+<div class="row">
+    <div class="col-sm-12">
+        <div class="ibox float-e-margins">
+
+            <div class="ibox-title">
+                <h5>会员管理</h5>
+            </div>
+            <div class="ibox-content">
+                <div class="row row-lg">
+                    <div class="col-sm-12">
+                        <div class="row">
+                            <div class="col-sm-3">
+                                <#NameCon id="vipName" name="会员名称" />
+                            </div>
+                            <div class="col-sm-3">
+                                <div class="input-group">
+                                    <div class="input-group-btn open">
+                                        <button data-toggle="dropdown" class="btn btn-white dropdown-toggle" type="button" aria-expanded="true">
+                                            可售状态
+                                        </button>
+                                    </div>
+                                    <select class="form-control" id="status" >
+                                        <option value="">全部</option>
+                                        <option value="1">上架</option>
+                                        <option value="2">下架</option>
+                                    </select>
+                                </div>
+                            </div>
+                        
+                    <div class="col-sm-3">
+                        <#button name="搜索" icon="fa-search" clickFun="Vip.search()"/>
+                        <#button name="重置" icon="fa-trash" clickFun="Vip.resetSearch()" space="true"/>
+                    </div>
+                </div>
+                <div class="hidden-xs" id="TCompetitionTableToolbar" role="group">
+                    <#button name="添加" icon="fa-plus" clickFun="Vip.add()"/>
+                    <#button name="编辑" icon="fa-edit" clickFun="Vip.edit()" space="true"/>
+                    <#button name="上架" icon="fa-check" clickFun="Vip.onShelf()" space="true"/>
+                    <#button name="下架" icon="fa-remove" clickFun="Vip.offShelf()" space="true"/>
+                    <#button name="查看详情" icon="fa-search" clickFun="Vip.detail()" space="true"/>
+                </div>
+                <#table id="VipTable"/>
+            </div>
+        </div>
+    </div>
+</div>
+</div>
+</div>
+<script src="${ctxPath}/modular/system/vip/vip.js"></script>
+
+@}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_add.html
new file mode 100644
index 0000000..d37da9d
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_add.html
@@ -0,0 +1,170 @@
+@layout("/common/_container.html"){
+<style>
+    .avatar-uploader .el-upload {
+        border: 1px dashed #d9d9d9;
+        border-radius: 6px;
+        cursor: pointer;
+        position: relative;
+        height: 100px;
+        width: 100px;
+        overflow: hidden;
+    }
+
+    .avatar-uploader .el-upload:hover {
+        border-color: #409eff;
+    }
+    .avatar-uploader-icon {
+        font-size: 28px;
+        color: #8c939d;
+        width: 100px;
+        height: 100px;
+        line-height: 100px;
+        margin-top: 34px;
+        text-align: center;
+    }
+    .avatar {
+        width: 100px;
+        height: 100px;
+        display: block;
+    }
+
+    .col-sm-12 {
+        margin-top: 20px;
+    }
+
+    .col-sm-12 select {
+        height: 33px;
+    }
+</style>
+<div class="ibox float-e-margins">
+    <div class="ibox-content">
+        <div class="form-horizontal" id="carInfoForm">
+            <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"  id="vipName"  placeholder="请输入会员名称" type="text">
+                </div>
+            </div>
+            <div class="form-group" style="display: flex" >
+                <label class="col-sm-3 control-label">*会员时长:</label>
+                <input class="form-control" style="width: 100px" id="time" name="time" type="number">
+                <div class="col-sm-9">
+                    <select style="width: 200px" class="form-control" id="timeType" name = "timeType" >
+                        <option value="1">天</option>
+                        <option value="2">月</option>
+                        <option value="3">年</option>
+                    </select>
+                </div>
+            </div>
+
+            <div class="form-group">
+                <label class="col-sm-3 control-label">售价:</label>
+                <div class="col-sm-9">
+                    <input style="width: 300px" class="form-control"  id="price" name="price" type="number">
+                </div>
+            </div>
+            <div class="row" id="storeSelect" >
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="col-sm-12">
+                            <label class="col-sm-3 control-label">*赠送优惠券: </label>
+                            <button onclick="couponList()"
+                                    style="height: 22px;width: 82px;background-color: #4a8ff1;color: white;z-index: 15;position:relative;border: none;margin-top: 1%">
+                                选择优惠券
+                            </button>
+                        </div>
+                        <div class="col-sm-12" style="margin-left: -57px;margin-top: 20px">
+                            <table class="table table-bordered" style="width: 70%;margin-left: 228px;" id="couponTable">
+                                <thead>
+                                <tr>
+                                    <td>优惠券名称</td>
+                                    <td>适用范围</td>
+                                    <td>优惠券类型</td>
+                                    <td>有效期</td>
+                                    <td>用户人群</td>
+                                    <td>数量</td>
+                                    <td>操作</td>
+                                </tr>
+                                </thead>
+                                <tbody id="coun"></tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="row" id="ticketSelect" >
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="col-sm-12">
+                            <label class="col-sm-3 control-label">*赠送门票: </label>
+                            <button onclick="ticketList()"
+                                    style="height: 22px;width: 82px;background-color: #4a8ff1;color: white;z-index: 15;position:relative;border: none;margin-top: 1%">
+                                添加门票
+                            </button>
+                        </div>
+                        <div class="col-sm-12" style="margin-left: -57px;margin-top: 20px">
+                            <table class="table table-bordered" style="width: 70%;margin-left: 228px;" id="ticketTable">
+                                <thead>
+                                <tr>
+                                    <td>门票名称</td>
+                                    <td>领取后X天有效</td>
+                                    <td>可用次数</td>
+                                    <td>操作</td>
+                                </tr>
+                                </thead>
+                                <tbody id="ticket"></tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+        </div>
+    </div>
+
+    <div class="row btn-group-m-t">
+        <div class="col-sm-10 col-sm-offset-5">
+            <#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="VipInfo.addSubmit()"/>
+            <#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="VipInfo.close()"/>
+        </div>
+    </div>
+</div>
+</div>
+</div>
+<script src="${ctxPath}/js/vue/vue.js"></script>
+<script src="${ctxPath}/js/elementui/index.js"></script>
+<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css">
+<script src="${ctxPath}/modular/system/vip/vip_info.js"></script>
+<script>
+
+    function couponList(){
+        var index = layer.open({
+            type: 2,
+            title: '优惠券列表',
+            area: ['80%', '80%'], //宽高
+            fix: false, //不固定
+            maxmin: true,
+            content: Feng.ctxPath + '/vip/couponList'
+        });
+        this.layerIndex = index;
+    }
+    
+    // 存储门票数据的数组
+    var ticketData = [];
+
+    function ticketList(){
+        var str="";
+        str += '<tr class="timeClass1">' +
+            '<td><input type="text" id="name" name="name" value="">' +
+            '<td><input type="number" id="time" name="time" value="">' +
+            '<td><input type="number" id="count" name="count" value=""' +
+            '</td><td><button onclick="deleteSub(this)">移除</button></td></tr>';
+
+        $("#ticket").append(str);
+    }
+    function deleteSub(e) {
+        $(e).parent().parent().remove();
+    }
+</script>
+@}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_detail.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_detail.html
new file mode 100644
index 0000000..2ecf5b6
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_detail.html
@@ -0,0 +1,184 @@
+@layout("/common/_container.html"){
+<style>
+    .avatar-uploader .el-upload {
+        border: 1px dashed #d9d9d9;
+        border-radius: 6px;
+        cursor: pointer;
+        position: relative;
+        height: 100px;
+        width: 100px;
+        overflow: hidden;
+    }
+
+    .avatar-uploader .el-upload:hover {
+        border-color: #409eff;
+    }
+    .avatar-uploader-icon {
+        font-size: 28px;
+        color: #8c939d;
+        width: 100px;
+        height: 100px;
+        line-height: 100px;
+        margin-top: 34px;
+        text-align: center;
+    }
+    .avatar {
+        width: 100px;
+        height: 100px;
+        display: block;
+    }
+
+    .col-sm-12 {
+        margin-top: 20px;
+    }
+
+    .col-sm-12 select {
+        height: 33px;
+    }
+</style>
+<div class="ibox float-e-margins">
+    <div class="ibox-content">
+        <div class="form-horizontal" id="carInfoForm">
+            <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"  id="vipName" value="${vip.vipName}"  placeholder="请输入会员名称" type="text">
+                </div>
+            </div>
+            <div class="form-group" style="display: flex" >
+                <label class="col-sm-3 control-label">*会员时长:</label>
+                <input class="form-control" style="width: 100px" id="time" value="${vip.time}" name="time" type="number">
+                <div class="col-sm-9">
+                    <select style="width: 200px" class="form-control" id="timeType" name = "timeType" >
+                        <option value="1" ${vip.timeType == 1 ? 'selected=selected' : ''}>天</option>
+                        <option value="2" ${vip.timeType == 2 ? 'selected=selected' : ''}>月</option>
+                        <option value="3" ${vip.timeType == 3 ? 'selected=selected' : ''}>年</option>
+                    </select>
+                </div>
+            </div>
+
+            <div class="form-group">
+                <label class="col-sm-3 control-label">售价:</label>
+                <div class="col-sm-9">
+                    <input style="width: 300px" class="form-control" value="${vip.price}"  id="price" name="price" type="number">
+                </div>
+            </div>
+            <div class="row" id="storeSelect" >
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="col-sm-12">
+                            <label class="col-sm-3 control-label">*赠送优惠券: </label>
+                            <button onclick="couponList()"
+                                    style="height: 22px;width: 82px;background-color: #4a8ff1;color: white;z-index: 15;position:relative;border: none;margin-top: 1%">
+                                选择优惠券
+                            </button>
+                        </div>
+                        <div class="col-sm-12" style="margin-left: -57px;margin-top: 20px">
+                            <table class="table table-bordered" style="width: 70%;margin-left: 228px;" id="couponTable">
+                                <thead>
+                                <tr>
+                                    <td>优惠券名称</td>
+                                    <td>适用范围</td>
+                                    <td>优惠券类型</td>
+                                    <td>有效期</td>
+                                    <td>用户人群</td>
+                                    <td>数量</td>
+                                    <td>操作</td>
+                                </tr>
+                                </thead>
+                                <tbody id="coun">
+                                @for(obj in couponList){
+                                <tr class="timeClass">
+                                    <td><input type="hidden" id="id" name="id" value="${obj.id}"><input type="hidden" id="name" name="name" value="${obj.name}">${obj.name}
+                                    <td><input type="hidden" id="useScope" name="useScope" value="${obj.useScope}">${obj.useScopeValue}
+                                    <td><input type="hidden" id="type" name="type" value="${obj.type}">${obj.typeValue}
+                                    <td><input type="hidden" id="timeValue" name="timeValue" value="${obj.timeValue}">${obj.timeValue}
+                                    <td><input type="hidden" id="userPopulation" name="userPopulation" value="${obj.userPopulation}">${obj.userPopulationValue}
+                                    <td><input type="number" id="count" name="count" value="${obj.count}">
+                                    </td><td><button onclick="deleteSub(this)">移除</button></td>
+                                </tr>
+                                @}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="row" id="ticketSelect" >
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="col-sm-12">
+                            <label class="col-sm-3 control-label">*赠送门票: </label>
+                            <button onclick="ticketList()"
+                                    style="height: 22px;width: 82px;background-color: #4a8ff1;color: white;z-index: 15;position:relative;border: none;margin-top: 1%">
+                                添加门票
+                            </button>
+                        </div>
+                        <div class="col-sm-12" style="margin-left: -57px;margin-top: 20px">
+                            <table class="table table-bordered" style="width: 70%;margin-left: 228px;" id="ticketTable">
+                                <thead>
+                                <tr>
+                                    <td>门票名称</td>
+                                    <td>领取后X天有效</td>
+                                    <td>可用次数</td>
+                                    <td>操作</td>
+                                </tr>
+                                </thead>
+                                <tbody id="ticket">
+                                @for(obj in ticketList){
+                                <tr class="timeClass1">
+                                    <td><input type="text" id="name" name="name" value="${obj.name}">
+                                    <td><input type="number" id="time" name="time" value="${obj.time}">
+                                    <td><input type="number" id="count" name="count" value="${obj.count}">
+                                    </td><td><button onclick="deleteSub(this)">移除</button></td></tr>
+                                </tr>
+                                @}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+        </div>
+    </div>
+</div>
+</div>
+</div>
+<script src="${ctxPath}/js/vue/vue.js"></script>
+<script src="${ctxPath}/js/elementui/index.js"></script>
+<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css">
+<script src="${ctxPath}/modular/system/vip/vip_info.js"></script>
+<script>
+
+    function couponList(){
+        var index = layer.open({
+            type: 2,
+            title: '优惠券列表',
+            area: ['80%', '80%'], //宽高
+            fix: false, //不固定
+            maxmin: true,
+            content: Feng.ctxPath + '/vip/couponList'
+        });
+        this.layerIndex = index;
+    }
+
+    // 存储门票数据的数组
+    var ticketData = [];
+
+    function ticketList(){
+        var str="";
+        str += '<tr class="timeClass1">' +
+            '<td><input type="text" id="name" name="name" value="">' +
+            '<td><input type="number" id="time" name="time" value="">' +
+            '<td><input type="number" id="count" name="count" value=""' +
+            '</td><td><button onclick="deleteSub(this)">移除</button></td></tr>';
+
+        $("#ticket").append(str);
+    }
+    function deleteSub(e) {
+        $(e).parent().parent().remove();
+    }
+</script>
+@}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_edit.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_edit.html
new file mode 100644
index 0000000..b79e4f6
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/vip/vip_edit.html
@@ -0,0 +1,191 @@
+@layout("/common/_container.html"){
+<style>
+    .avatar-uploader .el-upload {
+        border: 1px dashed #d9d9d9;
+        border-radius: 6px;
+        cursor: pointer;
+        position: relative;
+        height: 100px;
+        width: 100px;
+        overflow: hidden;
+    }
+
+    .avatar-uploader .el-upload:hover {
+        border-color: #409eff;
+    }
+    .avatar-uploader-icon {
+        font-size: 28px;
+        color: #8c939d;
+        width: 100px;
+        height: 100px;
+        line-height: 100px;
+        margin-top: 34px;
+        text-align: center;
+    }
+    .avatar {
+        width: 100px;
+        height: 100px;
+        display: block;
+    }
+
+    .col-sm-12 {
+        margin-top: 20px;
+    }
+
+    .col-sm-12 select {
+        height: 33px;
+    }
+</style>
+<div class="ibox float-e-margins">
+    <div class="ibox-content">
+        <div class="form-horizontal" id="carInfoForm">
+            <div class="form-group" >
+                <input type="hidden" id="vipId" value="${vip.id}">
+
+                <label class="col-sm-3 control-label">*会员名称:</label>
+                <div class="col-sm-9" style="display: flex;">
+                    <input style="width: 300px" class="form-control"  id="vipName" value="${vip.vipName}"  placeholder="请输入会员名称" type="text">
+                </div>
+            </div>
+            <div class="form-group" style="display: flex" >
+                <label class="col-sm-3 control-label">*会员时长:</label>
+                <input class="form-control" style="width: 100px" id="time" value="${vip.time}" name="time" type="number">
+                <div class="col-sm-9">
+                    <select style="width: 200px" class="form-control" id="timeType" name = "timeType" >
+                        <option value="1" ${vip.timeType == 1 ? 'selected=selected' : ''}>天</option>
+                        <option value="2" ${vip.timeType == 2 ? 'selected=selected' : ''}>月</option>
+                        <option value="3" ${vip.timeType == 3 ? 'selected=selected' : ''}>年</option>
+                    </select>
+                </div>
+            </div>
+
+            <div class="form-group">
+                <label class="col-sm-3 control-label">售价:</label>
+                <div class="col-sm-9">
+                    <input style="width: 300px" class="form-control" value="${vip.price}"  id="price" name="price" type="number">
+                </div>
+            </div>
+            <div class="row" id="storeSelect" >
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="col-sm-12">
+                            <label class="col-sm-3 control-label">*赠送优惠券: </label>
+                            <button onclick="couponList()"
+                                    style="height: 22px;width: 82px;background-color: #4a8ff1;color: white;z-index: 15;position:relative;border: none;margin-top: 1%">
+                                选择优惠券
+                            </button>
+                        </div>
+                        <div class="col-sm-12" style="margin-left: -57px;margin-top: 20px">
+                            <table class="table table-bordered" style="width: 70%;margin-left: 228px;" id="couponTable">
+                                <thead>
+                                <tr>
+                                    <td>优惠券名称</td>
+                                    <td>适用范围</td>
+                                    <td>优惠券类型</td>
+                                    <td>有效期</td>
+                                    <td>用户人群</td>
+                                    <td>数量</td>
+                                    <td>操作</td>
+                                </tr>
+                                </thead>
+                                <tbody id="coun">
+                                @for(obj in couponList){
+                                <tr class="timeClass">
+                                    <td><input type="hidden" id="id" name="id" value="${obj.id}"><input type="hidden" id="name" name="name" value="${obj.name}">${obj.name}
+                                    <td><input type="hidden" id="useScope" name="useScope" value="${obj.useScope}">${obj.useScopeValue}
+                                    <td><input type="hidden" id="type" name="type" value="${obj.type}">${obj.typeValue}
+                                    <td><input type="hidden" id="timeValue" name="timeValue" value="${obj.timeValue}">${obj.timeValue}
+                                    <td><input type="hidden" id="userPopulation" name="userPopulation" value="${obj.userPopulation}">${obj.userPopulationValue}
+                                    <td><input type="number" id="count" name="count" value="${obj.count}">
+                                    </td><td><button onclick="deleteSub(this)">移除</button></td>
+                                </tr>
+                                @}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="row" id="ticketSelect" >
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="col-sm-12">
+                            <label class="col-sm-3 control-label">*赠送门票: </label>
+                            <button onclick="ticketList()"
+                                    style="height: 22px;width: 82px;background-color: #4a8ff1;color: white;z-index: 15;position:relative;border: none;margin-top: 1%">
+                                添加门票
+                            </button>
+                        </div>
+                        <div class="col-sm-12" style="margin-left: -57px;margin-top: 20px">
+                            <table class="table table-bordered" style="width: 70%;margin-left: 228px;" id="ticketTable">
+                                <thead>
+                                <tr>
+                                    <td>门票名称</td>
+                                    <td>领取后X天有效</td>
+                                    <td>可用次数</td>
+                                    <td>操作</td>
+                                </tr>
+                                </thead>
+                                <tbody id="ticket">
+                                @for(obj in ticketList){
+                                <tr class="timeClass1">
+                                    <td><input type="text" id="name" name="name" value="${obj.name}">
+                                    <td><input type="number" id="time" name="time" value="${obj.time}">
+                                    <td><input type="number" id="count" name="count" value="${obj.count}">
+                                    </td><td><button onclick="deleteSub(this)">移除</button></td></tr>
+                                </tr>
+                                @}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="row btn-group-m-t">
+                <div class="col-sm-10 col-sm-offset-5">
+                    <#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="VipInfo.editSubmit()"/>
+                    <#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="VipInfo.close()"/>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</div>
+</div>
+<script src="${ctxPath}/js/vue/vue.js"></script>
+<script src="${ctxPath}/js/elementui/index.js"></script>
+<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css">
+<script src="${ctxPath}/modular/system/vip/vip_info.js"></script>
+<script>
+
+    function couponList(){
+        var index = layer.open({
+            type: 2,
+            title: '优惠券列表',
+            area: ['80%', '80%'], //宽高
+            fix: false, //不固定
+            maxmin: true,
+            content: Feng.ctxPath + '/vip/couponList'
+        });
+        this.layerIndex = index;
+    }
+
+    // 存储门票数据的数组
+    var ticketData = [];
+
+    function ticketList(){
+        var str="";
+        str += '<tr class="timeClass1">' +
+            '<td><input type="text" id="name" name="name" value="">' +
+            '<td><input type="number" id="time" name="time" value="">' +
+            '<td><input type="number" id="count" name="count" value=""' +
+            '</td><td><button onclick="deleteSub(this)">移除</button></td></tr>';
+
+        $("#ticket").append(str);
+    }
+    function deleteSub(e) {
+        $(e).parent().parent().remove();
+    }
+</script>
+@}
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/vip/TCoupon.js b/cloud-server-management/src/main/webapp/static/modular/system/vip/TCoupon.js
new file mode 100644
index 0000000..12aff73
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/static/modular/system/vip/TCoupon.js
@@ -0,0 +1,335 @@
+/**
+ * 管理初始化
+ */
+var TCoupon = {
+    id: "TCouponTable",	//表格id
+    seItem: null,		//选中的条目
+    table: null,
+    layerIndex: -1
+};
+
+/**
+ * 初始化表格的列
+ */
+TCoupon.initColumn = function () {
+    return [
+        {field: 'selectItem', checkbox: true},
+        {title: '序号', field: 'id', visible: true, align: 'center', valign: 'middle'},
+        {title: '优惠券名称', field: 'name', visible: true, align: 'center', valign: 'middle'},
+        {title: '适用范围', field: 'useScope', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "全国", 2: "指定城市", 3: "指定门店"}[value]
+            }
+        },
+        {title: '优惠券类型', field: 'type', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "满减券", 2: "代金券", 3: "体验券"}[value]
+            }},
+        {title: '发放方式', field: 'distributionMethod', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "积分购买", 2: "注册赠送", 3: "自动发券",4:"课包赠送"}[value]
+            }},
+        {title: '有效期', field: 'timeValue', visible: true, align: 'center', valign: 'middle'},
+        {title: '用户人群', field: 'userPopulation', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "全部用户", 2: "年度会员", 3: "已有学员用户"}[value]
+            }},
+        {title: '活动状态', field: 'status', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "未开始", 2: "已开始", 3: "已结束"}[value]
+            }},
+        {title: '可售状态', field: 'state', visible: true, align: 'center', valign: 'middle',
+            formatter: function (value, row, index) {
+                return {1: "上架", 2: "下架"}[value]
+            }},
+
+
+    ];
+};
+
+/**
+ * 检查是否选中
+ */
+TCoupon.check = function () {
+    var selected = $('#' + this.id).bootstrapTable('getSelections');
+    if(selected.length == 0){
+        Feng.info("请先选中表格中的某一记录!");
+        return false;
+    }else{
+        TCoupon.seItem = selected[0];
+        return true;
+    }
+};
+
+/**
+ * 点击添加
+ */
+TCoupon.openAdd = function () {
+    var index = layer.open({
+        type: 2,
+        title: '添加',
+        area: ['100%', '100%'], //宽高
+        fix: false, //不固定
+        maxmin: true,
+        content: Feng.ctxPath + '/tCouponManage/coupon_add'
+    });
+    this.layerIndex = index;
+};
+
+
+/**
+ * 点击编辑
+ */
+TCoupon.openChange = function () {
+    if (this.check()){
+        let size = TCoupon.seItem.size
+
+        if(size>0){
+            Feng.info("没有该权限");
+            return;
+        }
+        let publisherType = TCoupon.seItem.publisherType;
+        if ($("#objectType").val()==2){
+            if(publisherType != 1){
+                Feng.info("不能操作平台添加的优惠券");
+                return;
+            }
+        }
+        let id = TCoupon.seItem.id
+        let name = TCoupon.seItem.name
+        let quantityIssued = TCoupon.seItem.quantityIssued
+        let pickUpQuantity = TCoupon.seItem.pickUpQuantity
+        let illustrate = TCoupon.seItem.illustrate
+        let hasPickQty = TCoupon.seItem.hasPickQty
+        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">\n' +
+                '                                  <label class="form-control"  id="name" >'+name+'</label> '+
+                '                          </div>\n' +
+                '                        </div>\n'+
+            '                        <div class="form-group">\n' +
+                    '                            <label class="col-sm-3 control-label">发放数量:</label>\n' +
+                '                         <div class="col-sm-9">\n' +
+                '                                  <input class="form-control"  id="num" value="'+quantityIssued+'" > '+
+                '                          </div>\n' +
+                '                        </div>\n' +
+                '                        <div class="form-group">\n' +
+                '                            <label class="col-sm-3 control-label">限领数量:</label>\n' +
+                '                         <div class="col-sm-9">\n' +
+                '                                  <input class="form-control"  id="num1" value="'+pickUpQuantity+'" > '+
+                '                          </div>\n' +
+                '                        </div>\n' +
+                '                        <div class="form-group">\n' +
+                '                            <label class="col-sm-3 control-label">优惠券说明:</label>\n' +
+                '                         <div class="col-sm-9">\n' +
+                '                                  <textarea class="form-control"  id="text"  >'+illustrate+'</textarea> '+
+                '                          </div>\n' +
+                '                        </div>\n' +
+                '                       </div>' +
+                '                   </div>' +
+                '</div>'
+            , btn: ['关闭', '保存']
+            , btnAlign: 'c' //按钮居中
+            , shade:  0.5 //不显示遮罩
+            ,load:1
+            , yes: function () {
+                layer.closeAll();
+            },
+            btn2:function () {
+                let num = $("#num").val()
+                if(num==''){
+                    Feng.info("请输入发放数量")
+                    return false;
+                }
+                let num1 = $("#num1").val()
+                if(num1==''){
+                    Feng.info("请输入限领数量")
+                    return false;
+                }
+                let text = $("#text").val()
+                if(text==''){
+                    Feng.info("请输入优惠券说明")
+                    return false;
+                }
+
+                if(num<hasPickQty){
+                    Feng.info("发放数量不能小于已领取数量")
+                    return false;
+                }
+                var ajax = new $ax(Feng.ctxPath + "/tCouponManage/update", function (data) {
+                    if (data.code == 200) {
+                        Feng.success("操作成功!");
+                        window.location.reload();
+                        window.parent.layer.closeAll();
+                    } else if(data=="repeat"){
+                        window.location.reload();
+                        window.parent.layer.closeAll();
+                        Feng.error("请勿重复操作");
+                    }else {
+                        return  Feng.error(data.msg);
+                    }
+                }, function (data) {
+                    Feng.error("操作失败!")
+                    window.location.reload();
+                    window.parent.layer.closeAll();
+                    return   Feng.error("操作失败!");
+                });
+                ajax.set("id", id);
+                ajax.set("num", num);
+                ajax.set("num1", num1);
+                ajax.set("text", text);
+                ajax.start();
+                layer.closeAll();
+            }
+        });
+
+        this.layerIndex = index;
+    }
+};
+
+
+
+/**
+ * 上架
+ */
+
+
+/**
+ * 下架
+ */
+TCoupon.offShelf = function () {
+
+
+};
+
+
+/**
+ * 打开查看详情
+ */
+TCoupon.openDetail = function () {
+    if (this.check()) {
+        var index = layer.open({
+            type: 2,
+            title: '详情',
+            area: ['100%', '100%'], //宽高
+            fix: false, //不固定
+            maxmin: true,
+            content: Feng.ctxPath + '/tCouponManage/coupon_detail/' + TCoupon.seItem.id
+        });
+        this.layerIndex = index;
+    }
+};
+
+
+
+
+/**
+ * 打开领取记录
+ */
+TCoupon.openCollectionRecord = function () {
+    if (this.check()) {
+        var index = layer.open({
+            type: 2,
+            title: '详情',
+            area: ['800px', '420px'], //宽高
+            fix: false, //不固定
+            maxmin: true,
+            content: Feng.ctxPath + '/tCouponManage/coupon_record/' + TCoupon.seItem.id
+        });
+        this.layerIndex = index;
+    }
+};
+TCoupon.onShelf = function (e) {
+    if (this.check()) {
+        let size = TCoupon.seItem.size
+        if(size>0){
+            Feng.info("没有该权限");
+            return;
+        }
+        var ajax = new $ax(Feng.ctxPath + "/tCouponManage/onShelf", function(data){
+            if(data.code==200){
+                Feng.success("操作成功!")
+                TCoupon.table.refresh();
+            }
+        },function(data){
+            Feng.error("操作失败!" + data.responseJSON.message + "!");
+        });
+        ajax.set("id",TCoupon.seItem.id)
+        ajax.set("type",e)
+        ajax.start();
+    }
+};
+
+
+
+/**
+ * 查询列表
+ */
+TCoupon.search = function () {
+    var queryData = {};
+    queryData['name'] = $("#name").val();
+    queryData['type'] = $("#type").val();
+    queryData['status'] = $("#status").val();
+    queryData['state'] = $("#state").val();
+    TCoupon.table.refresh({query: queryData});
+};
+TCoupon.storeOfClosePage = function (){
+    parent.layer.close(parent.layer.getFrameIndex(window.frameElement.id));
+}
+
+TCoupon.saveSelectStores = function (){
+    var selected = $('#' + this.id).bootstrapTable('getSelections');
+    if (selected.length == 0) {
+        Feng.info("请先选中表格中的某一记录!");
+        return false;
+    }
+    var arr = [];
+    var name ='';
+    for(var i in selected){
+        console.log(selected)
+        if(typeof selected[i].id != "undefined"){
+            arr.push({
+                id: selected[i].id,
+                name: typeof selected[i].name != "undefined" ? selected[i].name : "",
+                useScope: typeof selected[i].useScope != "undefined" ? selected[i].useScope ==1?"全国":selected[i].useScope ==2?"指定城市":"指定门店" : "",
+                type: typeof selected[i].type != "undefined" ? selected[i].type ==1?"满减券":selected[i].useScope ==2?"代金券":"体验券" : "",
+                distributionMethod: typeof selected[i].distributionMethod != "undefined" ? selected[i].distributionMethod ==1?"积分购买":selected[i].distributionMethod ==2?"注册赠送":selected[i].distributionMethod ==3? "自动发券": "课包赠送":"",
+                timeValue: typeof selected[i].timeValue != "undefined" ? selected[i].timeValue : "",
+                userPopulation: typeof selected[i].userPopulation != "undefined" ? selected[i].userPopulation ==1?"全部用户":selected[i].userPopulation ==2?"会员":"已有学员用户" : "",
+                status: typeof selected[i].status != "undefined" ? selected[i].status ==1?"未开始":selected[i].useScope ==2?"已开始":"已结束" : "",
+                state: typeof selected[i].state != "undefined" ?selected[i].state ==1?"上架":"下架" : "",
+            })
+        }
+    }
+    console.log(arr)
+    window.parent.VipInfo.selecUserOpt(arr);
+    TCoupon.storeOfClosePage();
+}
+
+/**
+ * 重置搜索
+ */
+TCoupon.resetSearch = function () {
+    $("#name").val('');
+    $("#type").val('');
+    $("#status").val('');
+    $("#state").val('');
+    TCoupon.search();
+};
+
+$(function () {
+    var defaultColunms = TCoupon.initColumn();
+    var table = new BSTable(TCoupon.id, "/tCouponManage/listSelect", defaultColunms);
+    table.setPaginationType("client");
+    TCoupon.table = table.init();
+
+});
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/vip/vip.js b/cloud-server-management/src/main/webapp/static/modular/system/vip/vip.js
new file mode 100644
index 0000000..42ee1b4
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/static/modular/system/vip/vip.js
@@ -0,0 +1,557 @@
+/**
+ * 跨城站点管理管理初始化
+ */
+var Vip = {
+    id: "VipTable",	//表格id
+    seItem: null,		//选中的条目
+    table: null,
+    layerIndex: -1,
+    picture:"",
+    fileUrl:"",
+    img:"",
+    plan:"",
+    goodsPicArray:[],
+    validateFields: {
+    }
+};
+var objectType =$("#objectType").val()
+/**
+ * 初始化表格的列
+ */
+Vip.initColumn = function () {
+    return [
+        {field: 'selectItem', checkbox: true},
+        {title: '序号', field: 'id', visible: true, align: 'center', valign: 'middle'},
+        {title: '会员卡名称', field: 'vipName', visible: true, align: 'center', valign: 'middle'},
+        {title: '价格', field: 'price', visible: true, align: 'center', valign: 'middle'},
+        {title: '时长', field: 'time', visible: true, align: 'center', valign: 'middle'},
+        {
+            title: '状态', field: 'status', visible: true, align: 'center', valign: 'middle',
+            formatter: function(data) {
+                return {1: '上架中', 2: '下架中'}[data];
+            }
+        }
+    ];
+};
+
+/**
+ * 检查是否选中
+ */
+Vip.check = function () {
+    var selected = $('#' + this.id).bootstrapTable('getSelections');
+    if(selected.length == 0){
+        Feng.info("请先选中表格中的某一记录!");
+        return false;
+    }else{
+        Vip.seItem = selected[0];
+        return true;
+    }
+};
+/**
+ * 上架
+ */
+
+Vip.onShelf = function () {
+    if (this.check()){
+        var ajax = new $ax(Feng.ctxPath + "/vip/onShelf", function (data) {
+            Feng.success("上架成功!");
+            Vip.table.refresh();
+        }, function (data) {
+            Feng.error("上架失败!" + data.responseJSON.message + "!");
+        });
+        ajax.set("id",this.seItem.id);
+        ajax.start();
+    }
+};
+Vip.offShelf = function () {
+    if (this.check()){
+        var ajax = new $ax(Feng.ctxPath + "/vip/offShelf", function (data) {
+            Feng.success("下架成功!");
+            Vip.table.refresh();
+        }, function (data) {
+            Feng.error("下架失败!" + data.responseJSON.message + "!");
+        });
+        ajax.set("id",this.seItem.id);
+        ajax.start();
+    }
+};
+/**
+ * 下架
+ */
+Vip.offShelf = function () {
+    if (this.check()){
+        var selected = $('#' + this.id).bootstrapTable('getSelections');
+        const data1 = {
+            siteIds:[],
+            type:null
+        };
+        selected.forEach(function(obj) {
+            var id = obj.id;
+            data1.siteIds.push(id);
+        });
+        data1.type = 2;
+        $.ajax({
+            url: Feng.ctxPath + "/tSite/changeState",
+            type: "POST",
+            contentType: "application/json", // 设置请求头的 Content-Type
+            data: JSON.stringify(data1), // 将数据转换为 JSON 字符串
+            success: function(response) {
+                Feng.success("下架成功!");
+                Vip.search();
+            },
+            error: function(xhr, status, error) {
+                var errorMessage = xhr.responseText ? xhr.responseText : "下架失败!";
+                Feng.error("您的网络异常!");
+            }
+        });
+    }
+};
+/**
+ * 跳转添加场地页面
+ */
+Vip.add = function () {
+
+    var index = layer.open({
+        type: 2,
+        title: "添加会员卡",
+        area: ['100%', '100%'], //宽高
+        fix: false, //不固定
+        maxmin: true,
+        content: Feng.ctxPath + '/vip/add'
+    });
+    this.layerIndex = index;
+};
+
+/**
+ * 打开场地管理查看详情
+ */
+Vip.detail = function () {
+    var selected = $('#' + this.id).bootstrapTable('getSelections');
+    if(selected.length >1 ){
+        Feng.info("只能选择一个会员卡查看!");
+    }else {
+        if (this.check()) {
+            var index = layer.open({
+                type: 2,
+                title: "查看详情",
+                area: ['100%', '100%'], //宽高
+                fix: false, //不固定
+                maxmin: true,
+                content: Feng.ctxPath + '/vip/detail/' + Vip.seItem.id
+            });
+            this.layerIndex = index;
+        }
+    }
+};
+/**
+ * 打开场地管理编辑
+ */
+Vip.edit = function () {
+    var selected = $('#' + this.id).bootstrapTable('getSelections');
+    if(selected.length >1 ){
+        Feng.info("只能选择一个会员卡进行编辑!");
+    }else {
+    if (this.check()) {
+        var index = layer.open({
+            type: 2,
+            title: "编辑会员卡",
+            area: ['100%', '100%'], //宽高
+            fix: false, //不固定
+            maxmin: true,
+            content: Feng.ctxPath + '/vip/edit/' + Vip.seItem.id
+        });
+        this.layerIndex = index;
+    }
+    }
+};
+/**
+ * 关闭此对话框
+ */
+Vip.close = function() {
+    parent.layer.close(window.parent.Vip.layerIndex);
+}
+
+var sh = ""; // 门店经营开始时间:小时
+var sm = "";// 门店经营开始时间:分钟
+var eh = "";// 门店经营结束时间:小时
+var em = "";// 门店经营结束时间:分钟
+
+Vip.addSubmit = function(){
+    var data = {
+        province:"",
+        city:"",
+        cityManagerId:"",
+        storeId:"",
+        siteTypeId:null,
+        appointmentStartTime:"",
+        appointmentEndTime:"",
+        cashPrice:null,
+        playPaiCoin:null,
+        insuranceEndTime:"",
+        name:"",
+        insuranceImg:"",
+        managementPlan:"",
+        operatorId:"",
+        typeName:"",
+        nextName:"",
+        ishalf:"",
+        cashPriceOne:"",
+        playPaiCoinOne:"",
+        halfName:"",
+        introduce:"",
+        imgs:"",
+        reservation:"",
+        isCanBeBooked:"",
+        type:"",
+
+    };
+    data.province            = $("#pCode").val()
+    data.city                = $("#cCode").val()
+    data.cityManagerId       = $("#account").val()
+    data.storeId             = $("#store").val()
+    data.siteTypeId          = $("#siteTypeId").val()
+    data.appointmentStartTime= $("#start-time").val()
+    data.appointmentEndTime  = $("#end-time").val()
+    data.cashPrice           = $("#cashPrice").val()
+    data.playPaiCoin         = $("#playPaiCoin").val()
+    data.insuranceEndTime    = $("#insuranceEndTime").val()
+    data.name                = $("#name").val()
+    data.insuranceImg        = $("#img").val()
+    data.managementPlan      = $('#courseVideo').val()
+    data.typeName      = $('#siteTypeOne').val()
+    var sh =data.appointmentStartTime.split(':')[0];
+    var sm =data.appointmentStartTime.split(':')[1];
+    var eh =data.appointmentEndTime.split(':')[0];
+    var em =data.appointmentEndTime.split(':')[1];
+
+
+    console.log(data.typeName)
+
+    var reservation= $("input[name='reservation']:checked").val();
+    data.reservation= reservation;
+    data.isCanBeBooked= reservation;
+    console.log("看看是否可预约值")
+    console.log(reservation);
+    var checkbox = document.querySelector('input[name="pt"]');
+    console.log(checkbox)
+    if (checkbox!=null){
+        if (checkbox.checked) {
+            data.type = 1
+            console.log("选中是平台");
+            data.operatorId = 0;
+        } else {
+            console.log("运营商");
+            data.type = 2;
+        }
+    }
+
+    if (reservation == 1) {
+        if (data.typeName === "智慧场地") {
+            console.log("===========这是智慧球场")
+
+            console.log("=====" + data.appointmentStartTime)
+
+            var value = data.appointmentStartTime;
+            var lastTwoDigits = value.slice(-2);
+
+            if (lastTwoDigits === "00" || lastTwoDigits === "15" || lastTwoDigits === "30" || lastTwoDigits === "45") {
+                console.log("Last two digits are 00, 15, 30, or 45");
+            } else {
+                Feng.error("智慧场地的可预约时间段是15分钟的倍数")
+                return;
+
+            }
+
+
+            var value1 = data.appointmentEndTime;
+            var lastTwoDigits1 = value1.slice(-2);
+
+            if (lastTwoDigits1 === "00" || lastTwoDigits1 === "15" || lastTwoDigits1 === "30" || lastTwoDigits1 === "45") {
+                console.log("Last two digits are 00, 15, 30, or 45");
+            } else {
+                Feng.error("智慧场地的可预约时间段是15分钟的倍数")
+                return;
+
+            }
+
+
+        } else {
+            console.log("===========这是普通球场")
+
+            console.log("=====" + data.appointmentStartTime)
+            var value = data.appointmentStartTime;
+            var lastTwoDigits = value.slice(-2);
+
+            if (lastTwoDigits === "00" || lastTwoDigits === "30") {
+                console.log("Last two digits are 00, 15, 30, or 45");
+            } else {
+                Feng.info("普通场地可预约时间段需是30分钟的倍数")
+                return;
+            }
+
+
+            var value1 = data.appointmentEndTime;
+            var lastTwoDigits1 = value1.slice(-2);
+
+            if (lastTwoDigits1 === "00" || lastTwoDigits1 === "30") {
+                console.log("Last two digits are 00, 15, 30, or 45");
+            } else {
+                Feng.info("普通场地可预约时间段需是30分钟的倍数")
+                return;
+
+            }
+        }
+    }
+    var SelectValue="";
+    var getSelectValueMenbers = $("input[name='pt']:checked").each(function(j) {
+        if (j >= 0) {
+            SelectValue += $(this).val()
+        }
+    });
+    if(SelectValue==''){
+        let yys = $("#yys").val()
+        if(yys==""){
+            Feng.info("请选择运营商")
+            return;
+        }
+        SelectValue= yys
+    }
+    data.operatorId= SelectValue;
+    let num24 = $('input[name="name1"]');
+    var nextName="";
+    for (let i = 0; i < num24.length; i++) {
+        if($(num24[i]).val()==''){
+            Feng.info("请填写场地名称")
+            return;
+        }
+        if(i==num24.length-1){
+            nextName += $(num24[i]).val()
+        }else {
+            nextName += $(num24[i]).val()+","
+        }
+    }
+    data.nextName= nextName;
+    var ishalf= $("input[name='ishalf']:checked").val();
+    data.ishalf= ishalf;
+
+    var halfName="";
+    if (reservation==1) {
+        if (ishalf == 1) {
+            let cashPriceOne = $("#cashPriceOne").val()
+            if (cashPriceOne == '') {
+                Feng.info("请填写现金价格")
+                return;
+            }
+            data.cashPriceOne = cashPriceOne;
+
+            let playPaiCoinOne = $("#playPaiCoinOne").val()
+            if (playPaiCoinOne == '') {
+                Feng.info("请填写玩湃币价格")
+                return;
+            }
+
+            data.playPaiCoinOne = playPaiCoinOne;
+            let num2 = $('input[name="name2"]');
+            for (let i = 0; i < num2.length; i++) {
+                if ($(num2[i]).val() == '') {
+                    Feng.info("请填写半场名称")
+                    return;
+                }
+                if (i == num2.length - 1) {
+                    halfName += $(num2[i]).val()
+                } else {
+                    halfName += $(num2[i]).val() + ","
+                }
+            }
+        }
+    }
+
+
+    data.halfName= halfName;
+
+    let introduce ;
+    if (objectType==1){
+       introduce  = Vip.editor.getContent();
+    }
+
+    console.log(introduce)
+    if(introduce==""){
+        Feng.info("请输入公告内容")
+        return;
+    }
+    data.introduce= introduce;
+
+
+    var goodImgs = this.goodsPicArray;
+    if(objectType==1){
+        if(goodImgs.length==0){
+            Feng.info("请上传实景图")
+            return;
+        }
+    }
+
+    var imgOne ="";
+    for (let i = 0; i <goodImgs.length; i++) {
+        if(i==goodImgs.length-1){
+            imgOne += (goodImgs[i].response)
+        }else {
+            imgOne+=(goodImgs[i].response+",")
+        }
+
+    }
+    data.imgs = imgOne
+
+
+
+    if($("#store").val()=='' ){
+        Feng.info("请选择门店")
+        return;
+    }
+    if($("#siteTypeId").val()=='' ){
+        Feng.info("请选择场地分类")
+        return;
+    }
+    if($("#name").val()==''){
+        Feng.info("请输入场地名称")
+        return;
+    }
+
+    if (reservation==1){
+    if($("#start-time").val()=='' ){
+        Feng.info("请输入可预约时间段 开始时间")
+        return;
+    }
+    if($("#end-time").val()==''){
+        Feng.info("请输入可预约时间段 结束时间")
+        return;
+    }
+    if($("#cashPrice").val()==''){
+        Feng.info("请输入现金价格")
+        return;
+    }
+    if($("#playPaiCoin").val()==''){
+        Feng.info("请输入玩湃币价格")
+        return;
+    }
+    }
+    if($("#insuranceEndTime").val()==''){
+        Feng.info("请输入场地责任险有效期")
+        return;
+    }
+    if($("#img").val()==''){
+        Feng.info("请上传场地责任有效期图片")
+        return;
+    }
+    if($('#courseVideo').val()==''){
+        Feng.info("请上传消防及应急管理方案")
+        return;
+    }
+    var sTime = document.getElementById("start-time"); //获取输入的开始时间
+    var eTime  = document.getElementById("end-time"); // 获取输入的结束时间
+    var rStime = ""; //门店的经营开始时间
+    var rEtime = ""; //门店的经营结束时间
+    var selectedText = $('#store option:selected').text();
+    $.ajax({
+        url: Feng.ctxPath + "/tSite/getTime/" + selectedText,
+        type: "GET",
+        contentType: "application/json", // 设置请求头的 Content-Type
+        success: function (response) {
+            if (reservation==1) {
+                rStime = response.startTime;
+                sh = rStime.split(':')[0];// 门店经营开始时间:小时
+                sm = rStime.split(':')[1];// 门店经营开始时间:分钟
+
+                rEtime = response.endTime;
+                eh = rEtime.split(':')[0];// 门店经营结束时间:小时
+                em = rEtime.split(':')[1];// 门店经营结束时间:分钟
+
+                var start = sTime.value;
+                var startHour = start.split(':')[0];  // 输入的可预约开始时间:小时
+                var startMinute = start.split(':')[1];// 输入的可预约开始时间:分钟
+                if (Number(sh) > Number(startHour)) {
+                    Feng.error("预约的开始时间不应小于营业开始时间!")
+                    return false;
+                } else if (Number(sh) === Number(startHour)) {
+                    if (Number(sm) > Number(startMinute)) {
+                        Feng.error("预约的开始时间不应大于营业开始时间!")
+                        return false;
+                    }
+                } else if (Number(eh) < Number(startHour)) {
+                    Feng.error("预约的开始时间不应大于营业结束时间!")
+                    return false;
+                } else if (Number(eh) === Number(startHour)) {
+                    Feng.error("预约的开始时间不应大于等于营业结束时间!")
+                    return false;
+                }
+                var end = eTime.value;
+                var endHour = end.split(':')[0];  // 输入的可预约结束时间:小时
+                var endMinute = end.split(':')[1];// 输入的可预约结束时间:分钟
+                if (Number(eh) < Number(endHour)) {
+                    Feng.error("预约的结束时间不应大于营业结束时间!")
+                    return;
+                } else if (Number(eh) === Number(endHour)) {
+                    if (Number(em) < Number(endMinute)) {
+                        Feng.error("预约的开始时间不应大于开始营业时间!")
+                        return;
+                    }
+                } else if (Number(sh) > Number(endHour)) {
+                    Feng.error("预约的结束时间不应小于营业开始时间!")
+                    return;
+                }
+                if (Number(endHour) === Number(sh)) {
+                    if (Number(endMinute) < Number(sm)) {
+                        Feng.error("预约结束时间不应小于营业开始时间");
+                        return;
+                    }
+                }
+                if (Number(startHour) === Number(endHour) && Number(startMinute) === Number(endMinute)) {
+                    Feng.error("至少预约半个小时");
+                    return;
+                }
+            }
+            $.ajax({
+                url: Feng.ctxPath + "/tSite/addSite" ,
+                type: "POST",
+                data: JSON.stringify(data),
+                contentType: "application/json",
+                success: function (response) {
+                    window.parent.Vip.table.refresh();
+                    Vip.close();
+                    Feng.success("添加成功");
+                },
+                error: function (xhr, status, error) {
+                    Feng.error("添加失败!" + error);
+                }
+            });
+        },
+        error: function (xhr, status, error) {
+            var errorMessage = xhr.responseText ? xhr.responseText : "上架失败!";
+            Feng.error("您的网络异常!");
+            return false;
+        }
+    });
+};
+
+Vip.search = function () {
+    var queryData = {};
+    queryData['vipName'] = $("#vipName").val();
+    queryData['status'] = $("#status").val();
+    Vip.table.refresh({query: queryData});
+};
+
+Vip.resetSearch = function () {
+    $("#vipName").val("");
+    $("#status").val("");
+    Vip.search();
+};
+
+function UploadFileFn(){
+    $('#upFile').click();
+}
+
+$(function () {
+    var defaultColunms = Vip.initColumn();
+    var table = new BSTable(Vip.id, "/vip/list", defaultColunms);
+    table.setPaginationType("client");
+    Vip.table = table.init();
+});
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/vip/vip_info.js b/cloud-server-management/src/main/webapp/static/modular/system/vip/vip_info.js
new file mode 100644
index 0000000..71dad58
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/static/modular/system/vip/vip_info.js
@@ -0,0 +1,278 @@
+/**
+ * 初始化车辆管理详情对话框
+ */
+var language=1;
+var VipInfo = {
+    layerIndex: -1,
+    validateFields: {
+    },
+    goodsPicArray:[],
+    couponIds: [],
+
+};
+
+/**
+ * 验证数据是否为空
+ */
+VipInfo.validate = function () {
+    $('#carInfoForm').data("bootstrapValidator").resetForm();
+    $('#carInfoForm').bootstrapValidator('validate');
+    return $("#carInfoForm").data('bootstrapValidator').isValid();
+};
+
+/**
+ * 清除数据
+ */
+VipInfo.clearData = function() {
+    this.tCarInfoData = {};
+}
+
+/**
+ * 设置对话框中的数据
+ *
+ * @param key 数据的名称
+ * @param val 数据的具体值
+ */
+VipInfo.set = function(key, val) {
+    this.tCarInfoData[key] = (typeof val == "undefined") ? $("#" + key).val() : val;
+    return this;
+}
+
+/**
+ * 设置对话框中的数据
+ *
+ * @param key 数据的名称
+ * @param val 数据的具体值
+ */
+VipInfo.get = function(key) {
+    return $("#" + key).val();
+}
+VipInfo.selecUserOpt = function (arrays){
+    //获取所有的值
+    var subArr= this.couponIds;
+    $(".timeClass").each(function () {
+        subArr.push($(this).find("input[name*='id']").val());
+    });
+    var str = '';
+    for(var i in arrays){
+        var b = true;
+        for(var j in subArr){
+            if(arrays[i].id === Number(subArr[j])){
+                b = false;
+                break
+            }
+        }
+        if(b){
+            this.couponIds.push(arrays[i].id)
+            str += '<tr class="timeClass">' +
+                '<td><input type="hidden" id="id" name="id" value="'+arrays[i].id+'"><input type="hidden" id="name" name="name" value="'+arrays[i].name+'">' + arrays[i].name +
+                '<td><input type="hidden" id="useScope" name="useScope" value="'+arrays[i].useScope+'">' + arrays[i].useScope +
+                '<td><input type="hidden" id="type" name="type" value="'+arrays[i].type+'">' + arrays[i].type +
+                '<td><input type="hidden" id="timeValue" name="timeValue" value="'+arrays[i].timeValue+'">' + arrays[i].timeValue +
+                '<td><input type="hidden" id="userPopulation" name="userPopulation" value="'+arrays[i].userPopulation+'">' + arrays[i].userPopulation +
+                '<td><input type="number" id="count" name="count" value="1">' +
+                '</td><td><button onclick="deleteSub(this)">移除</button></td></tr>';
+        }
+    }
+    console.log("添加门店后的场地数组和门店数组")
+    console.log(this.storeIds)
+    console.log(this.siteIds)
+    $("#coun").append(str);
+}
+VipInfo.collectDataToJson = function() {
+    var dataArray = []; // 用于存储所有行数据的数组
+
+    // 遍历所有具有 timeClass 类的 tr 元素
+    $(".timeClass").each(function() {
+        var rowData = {}; // 用于存储当前行数据的对象
+
+        // 提取每个隐藏 input 的值并存入 rowData 对象
+        // 使用 $(this) 确保在当前行内查找
+        rowData.id = $(this).find("input[name='id']").val();
+        rowData.value = $(this).find("input[name='count']").val();
+
+        // 将当前行的数据对象添加到数组中
+        dataArray.push(rowData);
+    });
+
+    return dataArray;
+}
+
+VipInfo.collectDataToJson1 = function() {
+    var dataArray = []; // 用于存储所有行数据的数组
+
+    // 遍历所有具有 timeClass 类的 tr 元素
+    $(".timeClass1").each(function() {
+        var rowData = {}; // 用于存储当前行数据的对象
+
+        // 提取每个隐藏 input 的值并存入 rowData 对象
+        // 使用 $(this) 确保在当前行内查找
+        rowData.name = $(this).find("input[name='name']").val();
+        rowData.time = $(this).find("input[name='time']").val();
+        rowData.count = $(this).find("input[name='count']").val();
+        // 将当前行的数据对象添加到数组中
+        dataArray.push(rowData);
+    });
+
+
+
+    return dataArray; // 返回 JSON 字符串
+}
+
+function deleteSub(e) {
+    console.log(e);
+    var row = $(e).closest('tr');
+    var value = row.find('#id').val();
+    VipInfo.couponIds.splice(VipInfo.couponIds.indexOf(parseInt(value)), 1)
+    $(e).parent().parent().remove();
+    console.log('couponIds',VipInfo.couponIds)
+}
+VipInfo.addSubmit = function(){
+
+        if ($("#vipName").val() == '') {
+            Feng.info("请输入会员名称")
+            return;
+        }
+        if ($("#time").val() == '') {
+            Feng.info("请输入会员时长")
+            return;
+        }
+        if ($("#price").val() == '') {
+            Feng.info("请输入售价")
+            return;
+        }
+
+    var ajax = new $ax(Feng.ctxPath + "/vip/addVipInfo", function(data){
+            Feng.success("编辑成功!");
+            window.parent.Vip.table.refresh();
+        VipInfo.close();
+    });
+    var collectDataToJson = VipInfo.collectDataToJson();
+    var collectDataToJson1 = VipInfo.collectDataToJson1();
+    if (collectDataToJson.length == 0 && collectDataToJson1.length == 0){
+        Feng.error("优惠券和门票必须选择其中一类")
+        return;
+    }
+    if (collectDataToJson.length>0){
+        var collectDataToJson = JSON.stringify(collectDataToJson);
+        console.log("收集到的 优惠券JSON 数据:", collectDataToJson);
+        ajax.set("couponJson",collectDataToJson);
+
+    }
+    if (collectDataToJson1.length>0){
+        var collectDataToJson = JSON.stringify(collectDataToJson1);
+        console.log("收集到的 门票JSON 数据:", collectDataToJson);
+        ajax.set("ticketJson",collectDataToJson);
+
+    }
+    ajax.set("vipName",$("#vipName").val());
+    ajax.set("price",$("#price").val());
+    ajax.set("time",$("#time").val());
+    ajax.set("timeType",$("#timeType").val());
+    ajax.start();
+};
+VipInfo.editSubmit = function(){
+
+    if ($("#vipName").val() == '') {
+        Feng.info("请输入会员名称")
+        return;
+    }
+    if ($("#time").val() == '') {
+        Feng.info("请输入会员时长")
+        return;
+    }
+    if ($("#price").val() == '') {
+        Feng.info("请输入售价")
+        return;
+    }
+
+    var ajax = new $ax(Feng.ctxPath + "/vip/editVipInfo", function(data){
+        Feng.success("编辑成功!");
+        window.parent.Vip.table.refresh();
+        VipInfo.close();
+    });
+    var collectDataToJson = VipInfo.collectDataToJson();
+    var collectDataToJson1 = VipInfo.collectDataToJson1();
+    if (collectDataToJson.length == 0 && collectDataToJson1.length == 0){
+        Feng.error("优惠券和门票必须选择其中一类")
+        return;
+    }
+    if (collectDataToJson.length>0){
+        var collectDataToJson = JSON.stringify(collectDataToJson);
+        console.log("收集到的 优惠券JSON 数据:", collectDataToJson);
+        ajax.set("couponJson",collectDataToJson);
+
+    }
+    if (collectDataToJson1.length>0){
+        var collectDataToJson = JSON.stringify(collectDataToJson1);
+        console.log("收集到的 门票JSON 数据:", collectDataToJson);
+        ajax.set("ticketJson",collectDataToJson);
+
+    }
+    ajax.set("id",$("#vipId").val());
+
+    ajax.set("vipName",$("#vipName").val());
+    ajax.set("price",$("#price").val());
+    ajax.set("time",$("#time").val());
+    ajax.set("timeType",$("#timeType").val());
+    ajax.start();
+};
+VipInfo.close = function() {
+    parent.layer.close(window.parent.VipInfo.layerIndex);
+}
+VipInfo.oneChangeYys = function(e){
+    var oneId = $(e).val();
+    var checkbox = document.querySelector('input[name="pt"]');
+    if (checkbox.checked) {
+        oneId=0;
+        console.log("选中是平台");
+    }else{
+        oneId = 1;
+        console.log("运营商");
+        console.log(oneId)
+    }
+    if (oneId == "1"){
+        oneId = $("#yys").val()
+        if (oneId==""){
+            oneId = 1
+        }
+        console.log("看看选择之后")
+        console.log(oneId)
+        var button = document.getElementById("yys");
+        button.removeAttribute("disabled");
+    }
+    var ajax = new $ax(Feng.ctxPath + "/tSite/getChangeOne", function(data){
+        if(data!=null){
+            // var content1 = '<option value="0">平台</option>';
+            console.log("看看oneId")
+            console.log(oneId)
+            if (oneId == 0) {
+                console.log("锁住")
+                $("#yys").prop('disabled', true);
+            }else{
+                console.log("放开")
+                $("#yys").prop('disabled', false);
+            }
+
+            var content='<option value="">选择门店</option>';
+            $.each(data, function(k,v) {
+                content += "<option value='"+v.id+"'>"+v.name+"</option>";
+            });
+            $("#store").empty().append(content);
+        }
+    });
+
+
+
+    ajax.set("oneId",oneId);
+    ajax.start();
+};
+/**
+ * 关闭此对话框
+ */
+VipInfo.close = function() {
+    parent.layer.close(window.parent.Vip.layerIndex);
+}
+function UploadFileFn(){
+    $('#upFile').click();
+}

--
Gitblit v1.7.1