From fe3b034bfcb263336667bac9d4a002360533951b Mon Sep 17 00:00:00 2001
From: 44323 <443237572@qq.com>
Date: 星期三, 29 五月 2024 19:57:34 +0800
Subject: [PATCH] bug修改

---
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java      |  344 ++++++++++++++++-
 ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java      |    2 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStoryController.java      |   10 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUser.java                     |   11 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Recipient.java                 |    4 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/MyQrCodeUtil.java               |   93 ++++
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java           |    4 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java                |   10 
 ruoyi-service/ruoyi-goods/pom.xml                                                             |    5 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java      |  250 ++++++++++---
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java              |    6 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TSubjectController.java    |   10 
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java    |   16 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java       |  134 +++++-
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/QRCodeUtil.java                 |   50 ++
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java              |   38 ++
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java                  |    5 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java   |   85 ++++
 ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java |   10 
 ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java      |   21 +
 20 files changed, 967 insertions(+), 141 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java b/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java
index 0d0fcb6..298c98f 100644
--- a/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java
+++ b/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java
@@ -56,7 +56,7 @@
      *
      * @return 推荐商品信息
      */
-    @GetMapping("/goodRecommend")
+    @GetMapping("/base/goods/goodRecommend")
     @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"})
     R<List<TGoodsVO>> goodRecommend();
 
diff --git a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java
index 2e1d380..1e216f3 100644
--- a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java
@@ -144,6 +144,16 @@
             public R<Boolean> exchangeIntegral(Integer integral, String method) {
                 return R.fail("用户积分变动失败" + cause.getMessage());
             }
+
+            @Override
+            public R<Boolean> addIntegralDetail1(String integral, String method) {
+                return null;
+            }
+
+            @Override
+            public R<Boolean> exchangeIntegral1(Integer integral, String method) {
+                return null;
+            }
         };
     }
 }
diff --git a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java
index c3fb930..fb3d775 100644
--- a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java
+++ b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java
@@ -205,4 +205,25 @@
     @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
     R<Boolean> exchangeIntegral(@RequestParam("integral") Integer integral, @RequestParam("method") String method);
 
+    /**
+     * 生成积分明细-用于远程调用
+     *
+     * @param integral 积分变动信息
+     * @param method   变动源
+     * @return 操作结果
+     */
+    @GetMapping("/base/study/addIntegralDetail1")
+    R<Boolean> addIntegralDetail1(@RequestParam("integral") String integral, @RequestParam("method") String method);
+
+    /**
+     * 用户积分变动(增加或减少)-用于远程调用
+     *
+     * @param integral 积分变动信息
+     * @param method   变动源
+     * @return 操作结果
+     */
+    @GetMapping("/base/study/exchangeIntegral1")
+    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
+    R<Boolean> exchangeIntegral1(@RequestParam("integral") Integer integral, @RequestParam("method") String method);
+
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
index 2902af8..040f572 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -50,6 +50,10 @@
      * 成功标记
      */
     public static final Integer SUCCESS = 200;
+    /**
+     * 仅会员查看
+     */
+    public static final Integer VIP_ERROR = 501;
 
     /**
      * 失败标记
@@ -59,6 +63,18 @@
      * 登录失效
      */
     public static final Integer TOKEN_ERROR = 600;
+    /**
+     * 账号冻结
+     */
+    public static final Integer FREEZE = 502;
+    /**
+     * 短信验证码无效
+     */
+    public static final Integer ERRORCODE = 503;
+    /**
+     * 积分商城兑换失败code
+     */
+    public static final Integer EXCHANGECODE = 506;
 
     /**
      * 登录成功状态
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java
index 603a629..13477e8 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java
@@ -14,9 +14,20 @@
 
     /** 成功 */
     public static final int SUCCESS = Constants.SUCCESS;
+    public static final int VIPERROR = Constants.VIP_ERROR;
 
     /** 失败 */
     public static final int FAIL = Constants.FAIL;
+    /** 积分商城兑换失败 */
+    public static final int EXCHANGECODE = Constants.EXCHANGECODE;
+    /**
+     * 账号被冻结
+     */
+    public static final int FREEZE = Constants.FREEZE;
+    /**
+     * 短信验证码无效
+     */
+    public static final int ERRORCODE = Constants.ERRORCODE;
     /**
      * 登陆失效
      */
@@ -37,6 +48,10 @@
     {
         return restResult(data, SUCCESS, null);
     }
+    public static <T> R<T> vipError(String msg)
+    {
+        return restResult(null, VIPERROR, msg);
+    }
 
     public static <T> R<T> ok(T data, String msg)
     {
@@ -57,6 +72,29 @@
         return restResult(null, FAIL, msg);
     }
 
+    /**
+     * 商城兑换失败code
+     * @param msg
+     * @return
+     * @param <T>
+     */
+    public static <T> R<T> exchangeError(String msg)
+    {
+        return restResult(null, EXCHANGECODE, msg);
+    }
+    public static <T> R<T> freeze(String msg)
+    {
+        return restResult(null, FREEZE, msg);
+    }
+    public static <T> R<T> errorCode(String msg)
+    {
+        return restResult(null, ERRORCODE, msg);
+    }
+    public static <T> R<T> errCode(String msg)
+    {
+        return restResult(null, FREEZE, msg);
+    }
+
     public static <T> R<T> fail(T data)
     {
         return restResult(data, FAIL, null);
diff --git a/ruoyi-service/ruoyi-goods/pom.xml b/ruoyi-service/ruoyi-goods/pom.xml
index 954e482..a770520 100644
--- a/ruoyi-service/ruoyi-goods/pom.xml
+++ b/ruoyi-service/ruoyi-goods/pom.xml
@@ -17,6 +17,11 @@
     <dependencies>
 
         <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>javase</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+        <dependency>
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-api-study</artifactId>
             <version>3.6.2</version>
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
index 76d7e82..94ca279 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
@@ -1,6 +1,7 @@
 package com.ruoyi.goods.controller;
 
 
+import com.alibaba.fastjson2.util.UUIDUtils;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.web.page.PageInfo;
@@ -8,6 +9,8 @@
 import com.ruoyi.goods.domain.*;
 import com.ruoyi.goods.dto.*;
 import com.ruoyi.goods.service.*;
+import com.ruoyi.goods.utils.MyQrCodeUtil;
+import com.ruoyi.goods.utils.QRCodeUtil;
 import com.ruoyi.goods.vo.GoodDetailVO;
 import com.ruoyi.goods.vo.TGoodsVO;
 import com.ruoyi.goods.vo.TOrderVO;
@@ -16,18 +19,20 @@
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import org.apache.logging.log4j.core.util.UuidUtil;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import java.awt.image.BufferedImage;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
 
 /**
  * <p>
@@ -69,15 +74,46 @@
     }
 
     @PostMapping("/goodList")
-    @ApiOperation(value = "商品列表查询", tags = {"学习端-商品列表"})
+    @ApiOperation(value = "商品列表查询", tags = {"家长端-商品列表"})
     public R<PageInfo<TGoods>> listType(@RequestBody GoodQueryDTO goodQuery) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
         List<String> type = goodQuery.getType();
         String keywords = goodQuery.getKeywords();
         // 初始化条件构造器
         QueryWrapper<TGoods> wrapper = new QueryWrapper<>();
         wrapper = keywords != null && "".equals(keywords.trim()) ? wrapper.like("name", keywords) : wrapper;
+
         // 类型匹配 todo
-        wrapper = type.isEmpty() ? wrapper : wrapper.in("");
+        if (goodQuery.getType()!=null && goodQuery.getType().size()>0){
+            StringBuilder temp = new StringBuilder("");
+            for (String s : goodQuery.getType()) {
+                wrapper.or().apply("FIND_IN_SET('" + s + "', typeIds)"); // 将每个类型 ID 应用于 FIND_IN_SET 函数
+            }
+        }
+        wrapper.eq("isDelete", 0);
+        return R.ok(goodsService.page(new PageInfo<>(goodQuery.getPageNumber(), goodQuery.getPageSize()), wrapper));
+    }
+    @PostMapping("/goodListStudy")
+    @ApiOperation(value = "商品列表查询", tags = {"学习端"})
+    public R<PageInfo<TGoods>> goodListStudy(@RequestBody GoodQueryDTO goodQuery) {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
+        List<String> type = goodQuery.getType();
+        String keywords = goodQuery.getKeywords();
+        // 初始化条件构造器
+        QueryWrapper<TGoods> wrapper = new QueryWrapper<>();
+        wrapper = keywords != null && "".equals(keywords.trim()) ? wrapper.like("name", keywords) : wrapper;
+
+        // 类型匹配 todo
+        if (goodQuery.getType()!=null && goodQuery.getType().size()>0){
+            StringBuilder temp = new StringBuilder("");
+            for (String s : goodQuery.getType()) {
+                wrapper.or().apply("FIND_IN_SET('" + s + "', typeIds)"); // 将每个类型 ID 应用于 FIND_IN_SET 函数
+            }
+        }
         wrapper.eq("isDelete", 0);
         return R.ok(goodsService.page(new PageInfo<>(goodQuery.getPageNumber(), goodQuery.getPageSize()), wrapper));
     }
@@ -173,16 +209,44 @@
         return R.ok(orderService.lambdaQuery().eq(TOrder::getUserId, tokenService.getLoginUserStudy().getUserid())
                 .orderByDesc(TOrder::getCreateTime).list());
     }
+    @GetMapping("/exchangeRecordParent")
+    @ApiOperation(value = "家长端-兑换记录", tags = {"家长端-兑换记录"})
+    public R<List<TOrder>> exchangeRecordParent() {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        return R.ok(orderService.lambdaQuery().eq(TOrder::getUserId, tokenService.getLoginUser1().getUserid())
+                .orderByDesc(TOrder::getCreateTime).list());
+    }
 
     /**
      * 兑换记录
      */
     @GetMapping("/confirm")
-    @ApiOperation(value = "确认收货", tags = {"兑换记录"})
+    @ApiOperation(value = "确认收货", tags = {"家长端-兑换记录"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "订单id", name = "id", dataType = "String", required = true)
     })
     public R<Boolean> confirm(@RequestParam Integer id) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        TOrder byId = orderService.getById(id);
+        byId.setState(3);
+        return R.ok(orderService.updateById(byId));
+    }
+    /**
+     * 兑换记录
+     */
+    @GetMapping("/confirmStudy")
+    @ApiOperation(value = "确认收货", tags = {"学习端-兑换记录"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "订单id", name = "id", dataType = "String", required = true)
+    })
+    public R<Boolean> confirmStudy(@RequestParam Integer id) {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
         TOrder byId = orderService.getById(id);
         byId.setState(3);
         return R.ok(orderService.updateById(byId));
@@ -191,9 +255,93 @@
     /**
      * 获取用户收货地址
      */
+    @GetMapping("/shopAddressParent")
+    @ApiOperation(value = "获取用户收货地址", tags = {"家长端-获取用户收货地址"})
+    public R<List<Recipient>> shopAddressParent() {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        return R.ok(recipientService.lambdaQuery().eq(Recipient::getUserId,
+                tokenService.getLoginUser1().getUserid()).list());
+    }
+    /**
+     * 设置默认地址
+     */
+    @GetMapping("/setDefault")
+    @ApiOperation(value = "设置默认地址", tags = {"家长端-设置默认地址"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "地址id", name = "id", dataType = "String", required = true)
+    })
+    public R setDefault(@RequestParam Integer id) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient byId = recipientService.getById(id);
+        byId.setIsDefault(1);
+        recipientService.updateById(byId);
+        return R.ok();
+    }
+    /**
+     * 设置默认地址
+     */
+    @GetMapping("/setDefaultStudy")
+    @ApiOperation(value = "设置默认地址", tags = {"学习端-设置默认地址"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "地址id", name = "id", dataType = "String", required = true)
+    })
+    public R setDefaultStudy(@RequestParam Integer id) {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient byId = recipientService.getById(id);
+        byId.setIsDefault(1);
+        recipientService.updateById(byId);
+        return R.ok();
+    }
+
+    /**
+     * 根据地址id 获取详情
+     * @param id
+     * @return
+     */
+    @GetMapping("/getAddressById")
+    @ApiOperation(value = "获取地址详情", tags = {"家长端-获取地址详情"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "地址id", name = "id", dataType = "String", required = true)
+    })
+    public R<Recipient> getAddressById(@RequestParam Integer id) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient byId = recipientService.getById(id);
+        return R.ok(byId);
+    }
+    /**
+     * 根据地址id 获取详情
+     * @param id
+     * @return
+     */
+    @GetMapping("/getAddressByIdStudy")
+    @ApiOperation(value = "获取地址详情", tags = {"学习端-获取地址详情"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "地址id", name = "id", dataType = "String", required = true)
+    })
+    public R<Recipient> getAddressByIdStudy(@RequestParam Integer id) {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient byId = recipientService.getById(id);
+        return R.ok(byId);
+    }
+    /**
+     * 获取用户收货地址
+     */
     @GetMapping("/shopAddress")
-    @ApiOperation(value = "获取用户收货地址", tags = {"获取用户收货地址"})
+    @ApiOperation(value = "获取用户收货地址", tags = {"学习端-获取用户收货地址"})
     public R<List<Recipient>> shopAddress() {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
         return R.ok(recipientService.lambdaQuery().eq(Recipient::getUserId,
                 tokenService.getLoginUserStudy().getUserid()).list());
     }
@@ -202,10 +350,25 @@
      * 新增收货地址/修改收货地址
      */
     @PostMapping("/addressSaveOrUpdate")
-    @ApiOperation(value = "学习端-新增收货地址/修改收货地址", tags = {"新增收货地址/修改收货地址"})
+    @ApiOperation(value = "学习端-新增收货地址/修改收货地址", tags = {"学习端-新增收货地址/修改收货地址"})
     public R<String> addressSave(@RequestBody Recipient recipient) {
         recipient.setUserId(tokenService.getLoginUserStudy().getUserid());
-        return R.ok(recipientService.addressSaveOrUpdate(recipient));
+        recipientService.addressSaveOrUpdate(recipient);
+        return R.ok();
+    }
+    /**
+     * 新增收货地址/修改收货地址
+     */
+    @PostMapping("/addressSaveOrUpdateParent")
+    @ApiOperation(value = "家长端-新增收货地址/修改收货地址", tags = {"家长端-新增收货地址/修改收货地址"})
+    public R<String> addressSaveOrUpdateParent(@RequestBody Recipient recipient) {
+        recipient.setUserId(tokenService.getLoginUser1().getUserid());
+        if (recipient.getId() == null){
+            recipientService.updateById(recipient);
+        }else{
+            recipientService.save(recipient);
+        }
+        return R.ok();
     }
 
     /**
@@ -219,22 +382,71 @@
     public R<String> addressDelete(@RequestParam String id) {
         return R.ok(recipientService.removeById(id) ? "删除成功!" : "删除失败!");
     }
-
     /**
-     * 修改订单收货地址
-     *
-     * @param orderId 订单id
+     * 删除收货地址
      */
-    @GetMapping("/updateOrderAddress")
-    @ApiOperation(value = "学习端-修改订单收货地址", tags = {"学习端-修改订单收货地址"})
+    @GetMapping("/addressDeleteParent")
+    @ApiOperation(value = "家长端-删除收货地址", tags = {"家长端-删除收货地址"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "地址信息id", name = "id", dataType = "String", required = true)
+    })
+    public R<String> addressDeleteParent(@RequestParam String id) {
+        return R.ok(recipientService.removeById(id) ? "删除成功!" : "删除失败!");
+    }
+
+
+    @GetMapping("/getOrderAddressParent")
+    @ApiOperation(value = "获取修改订单收货地址", tags = {"家长端-获取修改订单收货地址"})
+    public R<List<Recipient>> getOrderAddressParent() {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
+                .eq("userId", tokenService.getLoginUser1().getUserid()));
+
+        return R.ok(userId);
+    }
+    @GetMapping("/getOrderAddress")
+    @ApiOperation(value = "获取修改订单收货地址", tags = {"学习端-获取修改订单收货地址"})
+    public R<List<Recipient>> getOrderAddress() {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
+        List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
+                .eq("userId", tokenService.getLoginUserStudy().getUserid()));
+        return R.ok(userId);
+    }
+    @GetMapping("/updateOrderAddressParent")
+    @ApiOperation(value = "修改订单收货地址", tags = {"家长端-修改订单收货地址"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "String", required = true),
-            @ApiImplicitParam(value = "完整收货地址", name = "address", dataType = "String", required = true)
+            @ApiImplicitParam(value = "地址信息id", name = "recipientId", dataType = "String", required = true)
     })
-    public R<Boolean> updateOrderAddress(@RequestParam String orderId,
-                                                  @RequestParam String address) {
-        return R.ok(orderService.lambdaUpdate().set(TOrder::getConsigneeAddress, address)
-                .eq(TOrder::getId, orderId).eq(TOrder::getState, 1).update());
+    public R updateOrderAddressParent(@RequestParam Integer orderId,@RequestParam Integer recipientId) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient userId = recipientService.getById(recipientId);
+        TOrder byId = orderService.getById(orderId);
+        byId.setConsigneeName(userId.getAddress());
+        byId.setConsigneePhone(userId.getRecipientPhone());
+        byId.setConsigneeAddress(userId.getAddress());
+        orderService.updateById(byId);
+        return R.ok("修改成功");
+    }
+    @GetMapping("/updateOrderAddress")
+    @ApiOperation(value = "修改订单收货地址", tags = {"学习端-修改订单收货地址"})
+    public R updateOrderAddress(@RequestParam Integer orderId,@RequestParam Integer recipientId) {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient userId = recipientService.getById(recipientId);
+        TOrder byId = orderService.getById(orderId);
+        byId.setConsigneeName(userId.getAddress());
+        byId.setConsigneePhone(userId.getRecipientPhone());
+        byId.setConsigneeAddress(userId.getAddress());
+        orderService.updateById(byId);
+        return R.ok();
     }
 
     /**
@@ -262,11 +474,33 @@
      * @param goodId 商品id
      */
     @GetMapping("/goodDetail")
-    @ApiOperation(value = "学习端-商品详情", tags = {"学习端-商品详情"})
+    @ApiOperation(value = "学习端-商品详情", tags = {"学习端-商城"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
     })
     public R<GoodDetailVO> goodDetail(@RequestParam String goodId) {
+        // 商品详情
+        TGoods goods = goodsService.lambdaQuery().eq(TGoods::getId, goodId).one();
+        // 商品分类详情
+        List<TGoodsType> goodsTypes = goodsTypeService.lambdaQuery().in(TGoodsType::getId, Arrays.asList(goods.getTypeIds().split(","))).list();
+        // 已兑换人数
+        int number = goods.getBasicCount() + orderService.getGoodBuyNumber(goods.getId());
+        return R.ok(new GoodDetailVO(goods, goodsTypes, number));
+    }
+    /**
+     * 商品详情
+     *
+     * @param goodId 商品id
+     */
+    @GetMapping("/goodDetailParent")
+    @ApiOperation(value = "商品详情", tags = {"家长端-商城"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
+    })
+    public R<GoodDetailVO> goodDetailParent(@RequestParam String goodId) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
         // 商品详情
         TGoods goods = goodsService.lambdaQuery().eq(TGoods::getId, goodId).one();
         // 商品分类详情
@@ -280,15 +514,63 @@
      * 商城-立即兑换
      */
     @GetMapping("/redeemNow")
-    @ApiOperation(value = "学习端-商城立即兑换", tags = {"学习端-商城立即兑换"})
+    @ApiOperation(value = "商城立即兑换", tags = {"学习端-商城"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
     })
     public R<GoodDetailVO> redeemNow(@RequestParam String goodId) {
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
         Recipient recipient = recipientService.lambdaQuery()
                 .eq(Recipient::getUserId, tokenService.getLoginUserStudy().getUserid())
                 .eq(Recipient::getIsDefault, 1).one();
-        return R.ok(goodsService.redeemNow(goodId, recipient));
+        GoodDetailVO goodDetailVO = goodsService.redeemNow(goodId, recipient);
+        LocalDateTime currentDateTime = LocalDateTime.now();
+        // 格式化日期和时间信息
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        String formattedDateTime = currentDateTime.format(formatter);
+        // 生成随机数,填充剩余位数
+        Random random = new Random();
+        StringBuilder randomPart = new StringBuilder();
+        for (int i = 0; i < 3; i++) {
+            randomPart.append((char) (random.nextInt(26) + 'A')); // 大写字母
+        }
+        // 组合订单编号
+        String orderNumber = formattedDateTime + randomPart.toString();
+        goodDetailVO.setOrderNumber(orderNumber);
+        return R.ok(goodDetailVO);
+    }
+    /**
+     * 商城-立即兑换
+     */
+    @GetMapping("/redeemNowParent")
+    @ApiOperation(value = "商城立即兑换", tags = {"家长端-商城"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
+    })
+    public R<GoodDetailVO> redeemNowParent(@RequestParam String goodId) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        Recipient recipient = recipientService.lambdaQuery()
+                .eq(Recipient::getUserId, tokenService.getLoginUser1().getUserid())
+                .eq(Recipient::getIsDefault, 1).one();
+        GoodDetailVO goodDetailVO = goodsService.redeemNow(goodId, recipient);
+        LocalDateTime currentDateTime = LocalDateTime.now();
+        // 格式化日期和时间信息
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        String formattedDateTime = currentDateTime.format(formatter);
+        // 生成随机数,填充剩余位数
+        Random random = new Random();
+        StringBuilder randomPart = new StringBuilder();
+        for (int i = 0; i < 3; i++) {
+            randomPart.append((char) (random.nextInt(26) + 'A')); // 大写字母
+        }
+        // 组合订单编号
+        String orderNumber = formattedDateTime + randomPart.toString();
+        goodDetailVO.setOrderNumber(orderNumber);
+        return R.ok(goodDetailVO);
     }
 
 
@@ -298,11 +580,19 @@
      * @param goodExchange 商品信息
      */
     @PostMapping("/goodExchange")
-    @ApiOperation(value = "学习端-商品兑换确认", tags = {"学习端-商品兑换确认"})
-    public R<Boolean> goodExchange(@RequestBody GoodExchangeDTO goodExchange) {
+    @ApiOperation(value = "学习端-商品兑换确认", tags = {"家长端-商品兑换确认"})
+    public R goodExchange(@RequestBody GoodExchangeDTO goodExchange) {
         Recipient recipient = recipientService.getById(goodExchange.getRecipientId());
-        return R.ok(goodsService.goodExchange(goodExchange, recipient));
+        return goodsService.goodExchange1(goodExchange, recipient);
     }
+    @PostMapping("/goodExchangeStudy")
+    @ApiOperation(value = "学习端-商品兑换确认", tags = {"学习端-商品兑换确认"})
+    public R goodExchangeStudy(@RequestBody GoodExchangeDTO goodExchange) {
+        Recipient recipient = recipientService.getById(goodExchange.getRecipientId());
+        return goodsService.goodExchange(goodExchange, recipient);
+    }
+
+
     @Autowired
     private StudyClient studyClient;
     @PostMapping("/getOrderInfo/{id}")
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Recipient.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Recipient.java
index ceadfb2..6420ebb 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Recipient.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Recipient.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.ruoyi.common.core.web.domain.BaseModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -19,7 +20,7 @@
  */
 @TableName("t_recipient")
 @Data
-public class Recipient extends Model<Recipient> {
+public class Recipient extends BaseModel {
 
     private static final long serialVersionUID = 1L;
 
@@ -31,6 +32,7 @@
     /**
      * 用户id
      */
+    @ApiModelProperty(value = "用户id")
     private Integer userId;
     /**
      * 收件人姓名
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java
index 93a57ea..11a00e6 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java
@@ -1,5 +1,6 @@
 package com.ruoyi.goods.dto;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 /**
@@ -13,26 +14,31 @@
     /**
      * 商品id
      */
+    @ApiModelProperty("商品id")
     private Integer goodId;
 
     /**
      * 备注
      */
+    @ApiModelProperty("备注")
     private String remark;
 
     /**
      * 兑换数量
      */
+    @ApiModelProperty("兑换数量")
     private Integer number;
 
     /**
      * 订单编号
      */
+    @ApiModelProperty("订单编号")
     private String orderNumber;
 
     /**
      * 收货地址id
      */
+    @ApiModelProperty("收货地址id")
     private String recipientId;
 
 }
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java
index c3342b5..5a590df 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java
@@ -2,6 +2,7 @@
 
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.domain.R;
 import com.ruoyi.goods.domain.Recipient;
 import com.ruoyi.goods.domain.TGoods;
 import com.ruoyi.goods.dto.GoodExchangeDTO;
@@ -44,5 +45,6 @@
      * @param recipient    收货地址
      * @return 兑换结果
      */
-    Boolean goodExchange(GoodExchangeDTO goodExchange, Recipient recipient);
+    R goodExchange(GoodExchangeDTO goodExchange, Recipient recipient);
+    R goodExchange1(GoodExchangeDTO goodExchange, Recipient recipient);
 }
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
index 5e1c1bc..4fcf5a4 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.constant.Constants;
 import com.ruoyi.common.core.constant.RedisConstants;
+import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.exception.GlobalException;
 import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.goods.domain.Recipient;
@@ -65,12 +66,12 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean goodExchange(GoodExchangeDTO goodExchange, Recipient recipient) {
+    public R goodExchange(GoodExchangeDTO goodExchange, Recipient recipient) {
         Integer number = goodExchange.getNumber();
         Integer goodId = goodExchange.getGoodId();
         TGoods good = this.getById(goodId);
         if (null == good) {
-            throw new GlobalException("商品不存在,请稍后重试!");
+            return R.exchangeError("商品不存在,请稍后重试!");
         }
         // 校验用户积分是否足够兑换
         TUser user = studyClient.userInfo().getData();
@@ -78,10 +79,9 @@
         if (user == null){
             user = studyClient.getUserById(loginUser1.getUserid()).getData();
         }
-
         int needIntegral = good.getIntegral() * number;
         if (user.getIntegral() < needIntegral) {
-            throw new GlobalException("兑换失败,当前剩余积分不足!");
+            return R.exchangeError("兑换失败,当前剩余积分不足!");
         }
         // 检查用户兑换数量是否超过单用户最大兑换数量
         List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getUserId, user.getId()).eq(TOrder::getGoodsId, goodId).list();
@@ -89,7 +89,7 @@
         int totalNumber = orderList.stream().map(TOrder::getCount).collect(Collectors.toList()).stream().mapToInt(Integer::intValue).sum();
         boolean canExchange = orderList.isEmpty() || null == good.getUserCount() || (totalNumber + number) <= good.getUserCount();
         if (!canExchange) {
-            throw new GlobalException("兑换失败,当前兑换数量已超过最大兑换数量,剩余兑换数量为: " + (good.getUserCount() - totalNumber) + "!");
+            return R.exchangeError("兑换失败,当前兑换数量已超过最大兑换数量,剩余兑换数量为: " + (good.getUserCount() - totalNumber) + "!");
         }
         // redisson分布式锁,防止超卖
         String key = String.format(RedisConstants.GOOD_STOCK, good.getId());
@@ -100,7 +100,7 @@
         // 兑换失败,库存不足
         if (!tried) {
             semaphore.release(number);
-            throw new GlobalException("当前商品库存不足!");
+            return R.exchangeError("当前商品库存不足");
         }
         // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务)
         TOrder order = orderInfo(goodExchange, recipient, number, goodId, needIntegral);
@@ -113,9 +113,63 @@
         result = result && this.lambdaUpdate().set(TGoods::getSurplus, good.getSurplus() - number).eq(TGoods::getId, good.getId()).update();
         if (!result) {
             semaphore.release(number);
-            throw new GlobalException("商品兑换失败!");
+            return R.exchangeError("商品兑换失败!");
         }
-        return result;
+        return R.ok();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R goodExchange1(GoodExchangeDTO goodExchange, Recipient recipient) {
+        Integer number = goodExchange.getNumber();
+        Integer goodId = goodExchange.getGoodId();
+        TGoods good = this.getById(goodId);
+        if (null == good) {
+            return R.exchangeError("商品不存在,请稍后重试!");
+        }
+        // 校验用户积分是否足够兑换
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        TUser user = studyClient.getUserById(tokenService.getLoginUser1().getUserid()).getData();
+
+        int needIntegral = good.getIntegral() * number;
+        if (user.getIntegral() < needIntegral) {
+            return R.exchangeError("兑换失败,当前剩余积分不足!");
+        }
+        // 检查用户兑换数量是否超过单用户最大兑换数量
+        List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getUserId, user.getId()).eq(TOrder::getGoodsId, goodId).list();
+        // 该商品订单为空、订单数量未超过商品的单个用户兑换上限数量时,可以进行兑换
+        int totalNumber = orderList.stream().map(TOrder::getCount).collect(Collectors.toList()).stream().mapToInt(Integer::intValue).sum();
+        boolean canExchange = orderList.isEmpty() || null == good.getUserCount() || (totalNumber + number) <= good.getUserCount();
+        if (!canExchange) {
+            return R.exchangeError("兑换失败,当前兑换数量已超过最大兑换数量,剩余兑换数量为: " + (good.getUserCount() - totalNumber) + "!");
+        }
+        // redisson分布式锁,防止超卖
+        String key = String.format(RedisConstants.GOOD_STOCK, good.getId());
+        RSemaphore semaphore = redissonClient.getSemaphore(key);
+        // 请求超时时间 单位:毫秒
+        semaphore.trySetPermits(1000);
+        boolean tried = semaphore.tryAcquire(number);
+        // 兑换失败,库存不足
+        if (!tried) {
+            semaphore.release(number);
+            return R.exchangeError("当前商品库存不足");
+        }
+        // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务)
+        TOrder order = orderInfo1(goodExchange, recipient, number, goodId, needIntegral);
+        boolean result = orderService.save(order);
+        // 远程调用,生成积分明细
+        result = result && studyClient.addIntegralDetail1(Constants.BURDEN + needIntegral, Constants.SHOPPING_CONSUME).getData();
+        // 扣除用户积分
+        result = result && studyClient.exchangeIntegral1(needIntegral, Constants.BURDEN).getData();
+        // 扣除库存
+        result = result && this.lambdaUpdate().set(TGoods::getSurplus, good.getSurplus() - number).eq(TGoods::getId, good.getId()).update();
+        if (!result) {
+            semaphore.release(number);
+            return R.exchangeError("商品兑换失败!");
+        }
+        return R.ok();
     }
 
     private TOrder orderInfo(GoodExchangeDTO goodExchange, Recipient recipient, Integer number, Integer goodId, int needIntegral) {
@@ -133,4 +187,19 @@
         order.setDisabled(Boolean.FALSE);
         return order;
     }
+    private TOrder orderInfo1(GoodExchangeDTO goodExchange, Recipient recipient, Integer number, Integer goodId, int needIntegral) {
+        TOrder order = new TOrder();
+        order.setOrderNumber(goodExchange.getOrderNumber());
+        order.setUserId(tokenService.getLoginUser1().getUserid());
+        order.setInsertTime(new Date());
+        order.setGoodsId(goodId);
+        order.setCount(number);
+        order.setState(1);
+        order.setIntegral(needIntegral);
+        order.setConsigneeName(recipient.getRecipient());
+        order.setConsigneePhone(recipient.getRecipientPhone());
+        order.setConsigneeAddress(recipient.getAddress());
+        order.setDisabled(Boolean.FALSE);
+        return order;
+    }
 }
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/MyQrCodeUtil.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/MyQrCodeUtil.java
new file mode 100644
index 0000000..1e65371
--- /dev/null
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/MyQrCodeUtil.java
@@ -0,0 +1,93 @@
+package com.ruoyi.goods.utils;
+
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MyQrCodeUtil {
+    //CODE_WIDTH:二维码宽度,单位像素
+    private static final int CODE_WIDTH = 400;
+    //CODE_HEIGHT:二维码高度,单位像素
+    private static final int CODE_HEIGHT = 400;
+    //FRONT_COLOR:二维码前景色,0x000000 表示黑色
+    private static final int FRONT_COLOR = 0x000000;
+    //BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色
+    //演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白
+    private static final int BACKGROUND_COLOR = 0xFFFFFF;
+    public static BufferedImage createCodeToFile(String content) {
+        try {
+            content = content.trim();
+            //核心代码-生成二维码
+            BufferedImage bufferedImage = getBufferedImage(content);
+
+            return bufferedImage;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+    /**
+     * 生成二维码并输出到输出流, 通常用于输出到网页上进行显示,输出到网页与输出到磁盘上的文件中,区别在于最后一句 ImageIO.write
+     * write(RenderedImage im,String formatName,File output):写到文件中
+     * write(RenderedImage im,String formatName,OutputStream output):输出到输出流中
+     * @param content  :二维码内容
+     * @param outputStream :输出流,比如 HttpServletResponse 的 getOutputStream
+     */
+    public static void createCodeToOutputStream(String content, OutputStream outputStream) {
+        try {
+            if (StringUtils.isBlank(content)) {
+                return;
+            }
+            content = content.trim();
+            //核心代码-生成二维码
+            BufferedImage bufferedImage = getBufferedImage(content);
+            //区别就是这一句,输出到输出流中,如果第三个参数是 File,则输出到文件中
+            ImageIO.write(bufferedImage, "png", outputStream);
+            System.out.println("二维码图片生成到输出流成功...");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    //核心代码-生成二维码
+    private static BufferedImage getBufferedImage(String content) throws WriterException {
+        //com.google.zxing.EncodeHintType:编码提示类型,枚举类型
+        Map<EncodeHintType, Object> hints = new HashMap();
+        //EncodeHintType.CHARACTER_SET:设置字符编码类型
+        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+        //EncodeHintType.ERROR_CORRECTION:设置误差校正
+        //ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
+        //不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
+        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
+        //EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
+        hints.put(EncodeHintType.MARGIN, 1);
+        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+        BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
+        BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
+        for (int x = 0; x < CODE_WIDTH; x++) {
+            for (int y = 0; y < CODE_HEIGHT; y++) {
+                bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
+            }
+        }
+        return bufferedImage;
+    }
+
+//    public static void main(String[] args) {
+//        String param = "{\n" +
+//                "    \"scan_type\": 1,\n" +
+//                "    \"space_id\": 2,\n" +
+//                "    \"sutu_id\": 3\n" +
+//                "}";
+//        createCodeToFile(param);
+//    }
+
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/QRCodeUtil.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/QRCodeUtil.java
new file mode 100644
index 0000000..00024c0
--- /dev/null
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/utils/QRCodeUtil.java
@@ -0,0 +1,50 @@
+package com.ruoyi.goods.utils;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import java.awt.image.BufferedImage;
+import java.util.Hashtable;
+
+/**
+ * @author chengst
+ * @date 2019/11/4
+ **/
+public class QRCodeUtil {
+
+    private final static String CHARSET = "utf-8";
+
+    private final static int QRSIZEE = 300;
+
+    // 二维码颜色
+    private static final int BLACK = 0xFF000000;
+    // 二维码颜色
+    private static final int WHITE = 0xFFFFFFFF;
+
+    public static BufferedImage createImage(String content){
+        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
+        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
+        hints.put(EncodeHintType.MARGIN, 1);
+        BitMatrix bitMatrix = null;
+        try {
+            bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRSIZEE, QRSIZEE,hints);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        int width = bitMatrix.getWidth();
+        int height = bitMatrix.getHeight();
+        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+
+        for (int x = 0; x < width; x++) {
+            for (int y = 0; y < height; y++) {
+                image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
+            }
+        }
+        return image;
+    }
+}
+
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
index 3be3b17..e5ca522 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
@@ -35,6 +35,11 @@
      */
     @ApiModelProperty("已兑换人数")
     private Integer exchangeNumber;
+    /**
+     * 已兑换人数
+     */
+    @ApiModelProperty("订单编号")
+    private String orderNumber;
 
     /**
      * 用户默认收货地址
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStoryController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStoryController.java
index 2ba4946..1e6ded7 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStoryController.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStoryController.java
@@ -51,7 +51,7 @@
     @Autowired
     private ITStoryService service;
     @PostMapping("/storyList")
-    @ApiOperation(value = "列表查询", tags = {"故事管理"})
+//    @ApiOperation(value = "列表查询", tags = {"故事管理"})
     public R<PageInfo<SubjectVO>> storyList(@RequestBody SubjectQuery query) {
         PageInfo<SubjectVO> res = new PageInfo<>(query.getPageNumber(), query.getPageSize());
         List<SubjectVO> list =  service.listAll(query);
@@ -76,7 +76,7 @@
         return R.ok(res);
     }
     @PostMapping("/add")
-    @ApiOperation(value = "添加", tags = {"故事管理"})
+//    @ApiOperation(value = "添加", tags = {"故事管理"})
     public R add(@RequestBody StoryDTO dto) {
         TStory tSubject = new TStory();
         BeanUtils.copyProperties(dto,tSubject);
@@ -84,7 +84,7 @@
         return R.ok("添加成功");
     }
     @PostMapping("/update")
-    @ApiOperation(value = "编辑", tags = {"故事管理"})
+//    @ApiOperation(value = "编辑", tags = {"故事管理"})
     public R update(@RequestBody StoryDTO dto) {
         TStory tSubject = new TStory();
         R<Object> week = getObjectR(dto.getId());
@@ -94,7 +94,7 @@
         return R.ok("编辑成功");
     }
     @PostMapping("/getInfo")
-    @ApiOperation(value = "查看详情", tags = {"故事管理"})
+//    @ApiOperation(value = "查看详情", tags = {"故事管理"})
     public R<StoryDTO> getInfo1(@RequestParam("id") Integer id) {
         TStory byId = service.getById(id);
         StoryDTO subjectDTO = new StoryDTO();
@@ -102,7 +102,7 @@
         return R.ok(subjectDTO);
     }
     @PostMapping("/updateState/{id}/{state}")
-    @ApiOperation(value = "修改状态", tags = {"故事管理"})
+//    @ApiOperation(value = "修改状态", tags = {"故事管理"})
     @ApiImplicitParams({
             @ApiImplicitParam(name = "id", value = "题目id", required = true),
             @ApiImplicitParam(name = "state", value = "1上架2下架3删除", required = true),
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
index 43045c2..97d187b 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
@@ -81,7 +81,7 @@
     private ITSubjectRecordService subjectRecordService;
 
     @PostMapping("/storyList")
-    @ApiOperation(value = "配置学习类型选择故事", tags = {"题目管理"})
+//    @ApiOperation(value = "配置学习类型选择故事", tags = {"题目管理"})
     public R<PageInfo<TStory>> storyList(@RequestBody ChoiceStory query) {
         PageInfo<TStory> res = new PageInfo<>(query.getPageNumber(), query.getPageSize());
         QueryWrapper<TStory> wrapper = new QueryWrapper<>();
@@ -117,7 +117,7 @@
     }
 
     @PostMapping("/subjectList")
-    @ApiOperation(value = "配置学习类型选择题目", tags = {"题目管理"})
+//    @ApiOperation(value = "配置学习类型选择题目", tags = {"题目管理"})
     public R<PageInfo<TSubject>> subjectList(@RequestBody ChoiceSubject query) {
         PageInfo<TSubject> res = new PageInfo<>(query.getPageNumber(), query.getPageSize());
         QueryWrapper<TSubject> wrapper = new QueryWrapper<>();
@@ -655,23 +655,18 @@
         return R.ok(res);
     }
 
-    /**
-     * 查询周目列表
-     *
-     * @param type    所属类型
-     * @param quarter 季度
-     */
-    @GetMapping("/weekList")
-    @ApiOperation(value = "根据季度获取周目列表", tags = {"根据季度获取周目列表"})
-    @ApiImplicitParams({
-            @ApiImplicitParam(value = "所属类型", name = "type", dataType = "Integer", required = true),
-            @ApiImplicitParam(value = "季度", name = "quarter", dataType = "Integer", required = true)
-    })
-    public R<List<StudyWeekDTO>> weekList(@RequestParam(defaultValue = "1") Integer type, @RequestParam Integer quarter) {
-        List<StudyWeekDTO> result = studyService.weekList(type, quarter);
-        return R.ok(result);
-    }
 
+
+
+
+    /**
+     * 可兑换商品推荐
+     */
+    @GetMapping("/goodRecommend")
+    @ApiOperation(value = "可兑换商品推荐", tags = {"学习端-首页"})
+    public R<List<TGoodsVO>> studySchedule() {
+        return R.ok(goodsClient.goodRecommend().getData());
+    }
     /**
      * 首次页面加载时调用,获取学习进度及学习时长等信息
      *
@@ -679,7 +674,7 @@
      * @param day  所属day
      */
     @GetMapping("/studySchedule")
-    @ApiOperation(value = "获取用户学习进度", tags = {"获取用户学习进度"})
+    @ApiOperation(value = "获取用户学习进度", tags = {"学习端-首页"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -688,16 +683,22 @@
         TUserStudy result = studyService.studySchedule(String.valueOf(tokenService.getLoginUserStudy().getUserid()), week, day);
         return R.ok(result);
     }
-
     /**
-     * 可兑换商品推荐
+     * 查询周目列表
+     *
+     * @param type    所属类型
+     * @param quarter 季度
      */
-    @GetMapping("/goodRecommend")
-    @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"})
-    public R<List<TGoodsVO>> studySchedule() {
-        return R.ok(goodsClient.goodRecommend().getData());
+    @GetMapping("/weekList")
+    @ApiOperation(value = "根据季度获取周目列表 ", tags = {"学习端-首页"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "所属类型 1.0只有类型听 传1", name = "type", dataType = "Integer", required = true),
+            @ApiImplicitParam(value = "季度 首次进入季度quarter默认传1", name = "quarter", dataType = "Integer", required = true)
+    })
+    public R<List<StudyWeekDTO>> weekList(@RequestParam(defaultValue = "1") Integer type, @RequestParam Integer quarter) {
+        List<StudyWeekDTO> result = studyService.weekList(type, quarter);
+        return R.ok(result);
     }
-
     /**
      * 进入题组后,获取题组学习进度信息
      *
@@ -705,7 +706,7 @@
      * @param day  所属day
      */
     @GetMapping("/teamSchedule")
-    @ApiOperation(value = "获取题组学习进度信息", tags = {"获取题组学习进度信息"})
+    @ApiOperation(value = "获取题组学习进度信息", tags = {"学习端-题目"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -720,7 +721,7 @@
      * 退出学习,记录学习进度、当日学习时长...
      */
     @PostMapping("/exitLearning")
-    @ApiOperation(value = "退出学习(记录学习进度等信息)", tags = {"退出学习(记录学习进度等信息)"})
+    @ApiOperation(value = "退出学习(记录学习进度等信息)", tags = {"学习端-题目"})
     public R<Boolean> exitLearning(@RequestBody TSubjectRecord subjectRecord) {
         // 学习时长处理
         return R.ok(subjectRecordService.updateById(subjectRecord));
@@ -733,7 +734,7 @@
      * @param day  所属day
      */
     @GetMapping("/listenSelectPicture")
-    @ApiOperation(value = "自主学习1-听音选图", tags = {"自主学习1-听音选图"})
+    @ApiOperation(value = "自主学习1-听音选图", tags = {"学习端-首页"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -743,11 +744,21 @@
         Boolean isVip = userService.isVip();
         LambdaQueryChainWrapper<TStudyListen> wrapper = studyListenService.lambdaQuery().eq(TStudyListen::getWeek, week)
                 .eq(TStudyListen::getDay, day).eq(TStudyListen::getDisabled, 0);
+
         // 非会员只能查看非会员题目,会员可以查看所有题目
-        if (!isVip) {
-            wrapper.eq(TStudyListen::getIsVip, 0);
-        }
+//        if (!isVip) {
+//            wrapper.eq(TStudyListen::getIsVip, 0);
+//        }
         List<TStudyListen> studyListens = wrapper.list();
+        for (TStudyListen studyListen : studyListens) {
+            if (studyListen.getIsVip() == 1){
+                // 需要会员查看
+                if (!isVip){
+                    // 不是会员
+                    return R.vipError("以下内容仅限会员查看,请通过家长端成为会员!");
+                }
+            }
+        }
         return R.ok(studyService.listenSelectPicture(week, day, studyListens));
     }
 
@@ -758,7 +769,7 @@
      * @param day  所属day
      */
     @GetMapping("/pictureSelectVoice")
-    @ApiOperation(value = "自主学习2-看图选音", tags = {"自主学习2-看图选音"})
+    @ApiOperation(value = "自主学习2-看图选音", tags = {"学习端-首页"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -769,11 +780,18 @@
         LambdaQueryChainWrapper<TStudyLook> wrapper = studyLookService.lambdaQuery().eq(TStudyLook::getWeek, week)
                 .eq(TStudyLook::getDay, day).eq(TStudyLook::getDisabled, 0);
         // 非会员只能查看非会员题目,会员可以查看所有题目
-        if (!isVip) {
-            wrapper.eq(TStudyLook::getIsVip, 0);
-        }
+
         List<TStudyLook> lookList = studyLookService.lambdaQuery().eq(TStudyLook::getWeek, week)
                 .eq(TStudyLook::getDay, day).eq(TStudyLook::getDisabled, 0).list();
+        for (TStudyLook studyListen : lookList) {
+            if (studyListen.getIsVip() == 1){
+                // 需要会员查看
+                if (!isVip){
+                    // 不是会员
+                    return R.vipError("以下内容仅限会员查看,请通过家长端成为会员!");
+                }
+            }
+        }
         return R.ok(studyService.pictureSelectVoice(week, day, lookList));
     }
 
@@ -784,7 +802,7 @@
      * @param day  所属day
      */
     @GetMapping("/induceExclude")
-    @ApiOperation(value = "自主学习3-归纳排除", tags = {"自主学习3-归纳排除"})
+    @ApiOperation(value = "自主学习3-归纳排除", tags = {"学习端-首页"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -795,10 +813,19 @@
         LambdaQueryChainWrapper<TStudyInduction> wrapper = studyInductionService.lambdaQuery().eq(TStudyInduction::getWeek, week)
                 .eq(TStudyInduction::getDay, day).eq(TStudyInduction::getDisabled, 0);
         // 非会员只能查看非会员题目,会员可以查看所有题目
-        if (!isVip) {
-            wrapper.eq(TStudyInduction::getIsVip, 0);
-        }
+//        if (!isVip) {
+//            wrapper.eq(TStudyInduction::getIsVip, 0);
+//        }
         List<TStudyInduction> inductionList = wrapper.list();
+        for (TStudyInduction studyListen : inductionList) {
+            if (studyListen.getIsVip() == 1){
+                // 需要会员查看
+                if (!isVip){
+                    // 不是会员
+                    return R.vipError("以下内容仅限会员查看,请通过家长端成为会员!");
+                }
+            }
+        }
         return R.ok(studyService.induceExclude(week, day, inductionList));
     }
 
@@ -809,7 +836,7 @@
      * @param day  所属day
      */
     @GetMapping("/questionsAndAnswers")
-    @ApiOperation(value = "自主学习4-有问有答", tags = {"自主学习4-有问有答"})
+    @ApiOperation(value = "自主学习4-有问有答", tags = {"学习端-首页"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -820,10 +847,19 @@
         LambdaQueryChainWrapper<TStudyAnswer> wrapper = studyAnswerService.lambdaQuery().eq(TStudyAnswer::getWeek, week)
                 .eq(TStudyAnswer::getDay, day).eq(TStudyAnswer::getDisabled, 0);
         // 非会员只能查看非会员题目,会员可以查看所有题目
-        if (!isVip) {
-            wrapper.eq(TStudyAnswer::getIsVip, 0);
-        }
+//        if (!isVip) {
+//            wrapper.eq(TStudyAnswer::getIsVip, 0);
+//        }
         List<TStudyAnswer> answerList = wrapper.list();
+        for (TStudyAnswer studyListen : answerList) {
+            if (studyListen.getIsVip() == 1){
+                // 需要会员查看
+                if (!isVip){
+                    // 不是会员
+                    return R.vipError("以下内容仅限会员查看,请通过家长端成为会员!");
+                }
+            }
+        }
         return R.ok(studyService.questionsAndAnswers(week, day, answerList));
     }
 
@@ -834,7 +870,7 @@
      * @param day  所属day
      */
     @GetMapping("/pictureMateVoice")
-    @ApiOperation(value = "自主学习5-音图相配", tags = {"自主学习5-音图相配"})
+    @ApiOperation(value = "自主学习5-音图相配", tags = {"学习端-首页"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
@@ -849,6 +885,13 @@
             wrapper.eq(TStudyPair::getIsVip, 0);
         }
         TStudyPair pair = wrapper.one();
+        if (pair.getIsVip() == 1){
+            // 需要会员查看
+            if (!isVip){
+                // 不是会员
+                return R.vipError("以下内容仅限会员查看,请通过家长端成为会员!");
+            }
+        }
         return R.ok(studyService.pictureMateVoice(week, day, pair));
     }
 
@@ -858,7 +901,7 @@
      * @param completeStudy 完成学习信息
      */
     @PostMapping("/completeLearning")
-    @ApiOperation(value = "完成学习", tags = {"完成学习"})
+    @ApiOperation(value = "完成学习", tags = {"学习端-题目"})
     public R<Boolean> completeLearning(@RequestBody CompleteStudyDTO completeStudy) {
         // 登录用户id
         Integer userId = tokenService.getLoginUserStudy().getUserid();
@@ -884,7 +927,7 @@
      * @param week       所属周目
      */
     @GetMapping("/gameHearing")
-    @ApiOperation(value = "自主游戏1-超级听力", tags = {"自主游戏1-超级听力(difficulty: 0入门、1中级、2高级)"})
+    @ApiOperation(value = "自主游戏1-超级听力", tags = {"学习端-游戏"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "难度(0入门、1中级、2困难)", name = "difficulty", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
@@ -924,7 +967,7 @@
      * @param week       所属周目
      */
     @GetMapping("/gameMemory")
-    @ApiOperation(value = "自主游戏2-超级记忆", tags = {"自主游戏2-超级记忆(difficulty: 0入门、1中级、2高级)"})
+    @ApiOperation(value = "自主游戏2-超级记忆", tags = {"学习端-游戏"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "难度(0入门、1中级、2困难)", name = "difficulty", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
@@ -961,7 +1004,7 @@
      * @param completeStudy 学习信息
      */
     @PostMapping("/gameAchievement")
-    @ApiOperation(value = "完成游戏-记录游戏测试成绩", tags = {"完成游戏-记录游戏测试成绩"})
+    @ApiOperation(value = "完成游戏-记录游戏测试成绩", tags = {"学习端-游戏"})
     public R<Boolean> gameAchievement(@RequestBody CompleteGameDTO completeStudy) {
         /*
          * 游戏测试需要根据正确率计算本次测试可获得积分
@@ -1019,7 +1062,7 @@
      * @param week 周目
      */
     @GetMapping("/lookPictureDbu")
-    @ApiOperation(value = "自主故事1-看图配音", tags = {"自主故事1-看图配音"})
+    @ApiOperation(value = "自主故事1-看图配音", tags = {"学习端-故事"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
     })
@@ -1038,7 +1081,7 @@
      * @param week 周目
      */
     @GetMapping("/frameworkMemory")
-    @ApiOperation(value = "自主故事2-框架记忆", tags = {"自主故事2-框架记忆"})
+    @ApiOperation(value = "自主故事2-框架记忆", tags = {"学习端-故事"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
     })
@@ -1055,7 +1098,7 @@
      * 完成故事类型
      */
     @GetMapping("/completeStory")
-    @ApiOperation(value = "完成故事学习", tags = {"完成故事学习"})
+    @ApiOperation(value = "完成故事学习", tags = {"学习端-故事"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "积分数量", name = "integral", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "故事id", name = "storyId", dataType = "Integer", required = true),
@@ -1085,9 +1128,10 @@
     }
 
     @GetMapping("/studyRecord")
-    @ApiOperation(value = "个人中心-学习记录", tags = {"个人中心-学习记录"})
+    @ApiOperation(value = "个人中心-学习记录", tags = {"学习端-个人中心"})
     public R<StudyRecordResultVO> studyRecord() {
         Integer userId = tokenService.getLoginUserStudy().getUserid();
+
         // 学习记录
         TUserStudy studyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                 .eq(TUserStudy::getDisabled, 0).one();
@@ -1096,18 +1140,75 @@
                 .eq(TGameRecord::getDisabled, 0).list();
         return R.ok(new StudyRecordResultVO(studyRecord, gameRecordList));
     }
+    @GetMapping("/record")
+    @ApiOperation(value = "游戏测试成绩", tags = {"家长端-游戏测试成绩"})
+    public R<StudyRecordResultVO> record() {
+        LoginUserParent loginUser1 = tokenService.getLoginUser1();
+        if (loginUser1 == null){
+            return R.tokenError("登陆失效,请重新登录");
+        }
+        Integer userId = loginUser1.getUserid();
+
+        // 学习记录
+        TUserStudy studyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
+                .eq(TUserStudy::getDisabled, 0).one();
+        // 查询剩余周目
+        if (studyRecord!=null){
+            int size = studyService.list(new QueryWrapper<TStudy>()
+                    .eq("type", 1)).size();
+            studyRecord.setSurplus(size-studyRecord.getWeek());
+        }else{
+            studyRecord.setSurplus(studyService.list(new QueryWrapper<TStudy>()
+                    .eq("type", 1)).size());
+        }
+        // 游戏测试成绩
+        List<TGameRecord> gameRecordList = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId)
+                .eq(TGameRecord::getDisabled, 0).list();
+        return R.ok(new StudyRecordResultVO(studyRecord, gameRecordList));
+    }
+    @GetMapping("/getIntegral")
+    @ApiOperation(value = "获取剩余积分", tags = {"家长端-获取剩余积分"})
+    public R<Integer> getIntegral() {
+        Integer userId = tokenService.getLoginUser1().getUserid();
+        return R.ok(userService.getById(userId).getIntegral());
+    }
+    @GetMapping("/getIntegralStudy")
+    @ApiOperation(value = "获取剩余积分", tags = {"学习端-获取剩余积分"})
+    public R<Integer> getIntegralStudy() {
+        Integer userId = tokenService.getLoginUserStudy().getUserid();
+        return R.ok(userService.getById(userId).getIntegral());
+    }
 
     @GetMapping("/integralDetail")
-    @ApiOperation(value = "个人中心-积分明细", tags = {"个人中心-积分明细"})
+    @ApiOperation(value = "个人中心-积分明细", tags = {"学习端-个人中心"})
     @ApiImplicitParams({
-            @ApiImplicitParam(value = "查询时间", name = "time", dataType = "Integer"),
+            @ApiImplicitParam(value = "查询时间 格式yyyy-MM", name = "time", dataType = "Integer"),
             @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "每页显示条数", name = "pageSize", dataType = "Integer", required = true)
     })
     public R<IPage<TIntegralRecord>> integralDetail(String time,
                                                     @RequestParam("pageNum") Integer pageNum,
                                                     @RequestParam("pageSize") Integer pageSize) {
+        if(tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
         return R.ok(integralRecordService.integralDetail(new Page<>(pageNum, pageSize), tokenService.getLoginUserStudy().getUserid(), time));
+    }
+    @GetMapping("/integralDetailParent")
+    @ApiOperation(value = "个人中心-积分明细", tags = {"家长端"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "查询时间 格式yyyy-MM", name = "time", dataType = "Integer"),
+            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
+            @ApiImplicitParam(value = "每页显示条数", name = "pageSize", dataType = "Integer", required = true)
+    })
+    public R<IPage<TIntegralRecord>> integralDetailParent(String time,
+                                                    @RequestParam("pageNum") Integer pageNum,
+                                                    @RequestParam("pageSize") Integer pageSize) {
+        if(tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+
+        return R.ok(integralRecordService.integralDetail(new Page<>(pageNum, pageSize), tokenService.getLoginUser1().getUserid(), time));
     }
 
     /**
@@ -1117,7 +1218,7 @@
      * @param method   变动源
      */
     @GetMapping("/addIntegralDetail")
-    @ApiOperation(value = "添加-积分明细", tags = {"添加-积分明细"})
+//    @ApiOperation(value = "添加-积分明细", tags = {"添加-积分明细"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "积分数量", name = "integral", dataType = "Integer", required = true),
             @ApiImplicitParam(value = "变动源(完成学习、完成游戏...)", name = "method", dataType = "String", required = true)
@@ -1125,6 +1226,30 @@
     public R<Boolean> addIntegralDetail(@RequestParam("integral") String integral, @RequestParam("method") String method) {
         // 当前登录用户
         LoginUserParent userStudy = tokenService.getLoginUserStudy();
+        // 生成积分明细信息
+        TIntegralRecord integralRecord = new TIntegralRecord();
+        integralRecord.setIntegral(integral);
+        integralRecord.setMethod(method);
+        integralRecord.setUserId(userStudy.getUserid());
+        integralRecord.setDisabled(Boolean.FALSE);
+        integralRecord.setCreateBy(userStudy.getPhone());
+        integralRecord.setCreateTime(new Date());
+        integralRecord.setUpdateBy(userStudy.getPhone());
+        integralRecord.setUpdateTime(new Date());
+        return R.ok(integralRecordService.save(integralRecord));
+    }
+    @GetMapping("/addIntegralDetail1")
+//    @ApiOperation(value = "添加-积分明细", tags = {"添加-积分明细"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "积分数量", name = "integral", dataType = "Integer", required = true),
+            @ApiImplicitParam(value = "变动源(完成学习、完成游戏...)", name = "method", dataType = "String", required = true)
+    })
+    public R addIntegralDetail1(@RequestParam("integral") String integral, @RequestParam("method") String method) {
+        // 当前登录用户
+        LoginUserParent userStudy = tokenService.getLoginUser1();
+        if (userStudy == null){
+            return R.tokenError("登录失效");
+        }
         // 生成积分明细信息
         TIntegralRecord integralRecord = new TIntegralRecord();
         integralRecord.setIntegral(integral);
@@ -1145,7 +1270,7 @@
      * @param method   变动源
      */
     @GetMapping("/exchangeIntegral")
-    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
+//    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
     public R<Boolean> exchangeIntegral(@RequestParam("integral") Integer integral, @RequestParam("method") String method) {
         TUser user = userService.getById(tokenService.getLoginUserStudy().getUserid());
         if (Constants.BURDEN.equals(method)) {
@@ -1155,6 +1280,17 @@
         }
         return R.ok(userService.updateById(user));
     }
+    @GetMapping("/exchangeIntegral1")
+//    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
+    public R<Boolean> exchangeIntegral1(@RequestParam("integral") Integer integral, @RequestParam("method") String method) {
+        TUser user = userService.getById(tokenService.getLoginUser1().getUserid());
+        if (Constants.BURDEN.equals(method)) {
+            user.setIntegral(user.getIntegral() - integral);
+        } else {
+            user.setIntegral(user.getIntegral() + integral);
+        }
+        return R.ok(userService.updateById(user));
+    }
 
 }
 
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TSubjectController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TSubjectController.java
index 32a9e8a..912bab1 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TSubjectController.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TSubjectController.java
@@ -52,7 +52,7 @@
 
 
     @PostMapping("/subjectList")
-    @ApiOperation(value = "列表查询", tags = {"题目管理"})
+//    @ApiOperation(value = "列表查询", tags = {"题目管理"})
     public R<PageInfo<SubjectVO>> subjectList(@RequestBody SubjectQuery query) {
         PageInfo<SubjectVO> res = new PageInfo<>(query.getPageNumber(), query.getPageSize());
         List<SubjectVO> list =  subjectService.listAll(query);
@@ -86,7 +86,7 @@
         return R.ok(res);
     }
     @PostMapping("/add")
-    @ApiOperation(value = "添加", tags = {"题目管理"})
+//    @ApiOperation(value = "添加", tags = {"题目管理"})
     public R add(@RequestBody SubjectDTO dto) {
         TSubject tSubject = new TSubject();
         BeanUtils.copyProperties(dto,tSubject);
@@ -94,7 +94,7 @@
         return R.ok("添加成功");
     }
     @PostMapping("/update")
-    @ApiOperation(value = "编辑", tags = {"题目管理"})
+//    @ApiOperation(value = "编辑", tags = {"题目管理"})
     public R update(@RequestBody SubjectDTO dto) {
         TSubject tSubject = new TSubject();
         // 判断当前题目有没有被使用
@@ -174,7 +174,7 @@
     }
 
     @PostMapping("/getInfo")
-    @ApiOperation(value = "查看详情", tags = {"题目管理"})
+//    @ApiOperation(value = "查看详情", tags = {"题目管理"})
     public R<SubjectDTO> getInfo(@RequestParam("id") Integer id) {
         TSubject byId = subjectService.getById(id);
         SubjectDTO subjectDTO = new SubjectDTO();
@@ -182,7 +182,7 @@
         return R.ok(subjectDTO);
     }
     @PostMapping("/updateState/{id}/{state}")
-    @ApiOperation(value = "修改状态", tags = {"题目管理"})
+//    @ApiOperation(value = "修改状态", tags = {"题目管理"})
     @ApiImplicitParams({
             @ApiImplicitParam(name = "id", value = "题目id", required = true),
             @ApiImplicitParam(name = "state", value = "1上架2下架3删除", required = true),
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
index 27b4b4a..b60d3d6 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
@@ -325,9 +325,26 @@
         }
         return R.ok();
     }
-
+    @PostMapping("/getUserInfoParent")
+    @ApiOperation(value = "获取用户信息", tags = {"家长端-获取用户信息"})
+    public R<TUser> getUserInfo() {
+        LoginUserParent loginUser1 = tokenService.getLoginUser1();
+        if (loginUser1!=null){
+            TUser byId = userService.getById(loginUser1.getUserid());
+            if (byId.getVipEndTime() == null){
+                byId.setIsVip(0);
+            }else if (byId.getVipEndTime().after(new Date())){
+                byId.setIsVip(1);
+            }else{
+                byId.setIsVip(0);
+            }
+            return R.ok(byId);
+        }else{
+            return R.tokenError("登录失效");
+        }
+    }
     @PostMapping("/parentPage")
-    @ApiOperation(value = "平板", tags = {"家长端-启动页"})
+    @ApiOperation(value = "平板", tags = {"启动页"})
     public R<String> parentPage() {
         List<TPage> data = managementClient.getPage1().getData();
         for (TPage datum : data) {
@@ -339,7 +356,7 @@
     }
 
     @PostMapping("/parentPage1")
-    @ApiOperation(value = "手机", tags = {"家长端-启动页"})
+    @ApiOperation(value = "手机", tags = {"启动页"})
     public R<String> parentPage1() {
         List<TPage> data = managementClient.getPage1().getData();
         for (TPage datum : data) {
@@ -351,7 +368,7 @@
     }
 
     @PostMapping("/getProtocol")
-    @ApiOperation(value = "获取协议", tags = {"家长端-协议"})
+    @ApiOperation(value = "获取协议", tags = {"协议"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "类型 1用户 2隐私 3注销", name = "type", dataType = "string", required = true),
     })
@@ -371,7 +388,7 @@
     @ApiOperation(value = "反馈", tags = {"家长端-意见反馈"})
     public R<String> feedBack(@RequestBody TFeedback dto) {
         if (tokenService.getLoginUser1() == null) {
-            throw new GlobalException("登录失效!");
+            return R.tokenError("登录失效");
         }
         LoginUserParent loginUser1 = tokenService.getLoginUser1();
         dto.setUserId(loginUser1.getUserid());
@@ -395,8 +412,8 @@
             }
         } else {
             // 手机验证码校验
-            Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
             if (!phoneCode.equals("123456")){
+            Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
                 if (null == redisPhoneCode) {
                     throw new GlobalException("登录失败,手机验证码已过期!");
                 } else {
@@ -433,7 +450,7 @@
      */
     @PostMapping("/studyLogin")
     @ApiOperation(value = "学习端-登录", tags = {"学习端-登录"})
-    public R<Map<String, Object>> studyLogin(@RequestBody @Validated RegisterPhoneRequest phoneRequest) {
+    public R<Map<String, Object>> studyLogin(@RequestBody RegisterPhoneRequest phoneRequest) {
         String phone = phoneRequest.getPhone();
         String phoneCode = phoneRequest.getPhoneCode();
         TUser user = userService.getOne(new QueryWrapper<TUser>()
@@ -441,23 +458,28 @@
                 .eq("phone", phone));
         if (user != null) {
             if (user.getState() == 2) {
-                throw new GlobalException("登录失败,您的账号已被冻结!");
+                return R.freeze("登录失败,您的账号已被冻结!");
             }
         } else {
-            // 手机验证码校验
-            Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
-            if (null == redisPhoneCode) {
-                throw new GlobalException("登录失败,手机验证码已过期!");
-            } else {
-                // redis 验证码的value 为 code:时间戳
-                String rCodeAndTime = String.valueOf(redisPhoneCode);
-                String rCode = rCodeAndTime.split(":")[0];
-                if (!rCode.equalsIgnoreCase(phoneCode)) {
-                    throw new GlobalException("登录失败,手机验证码输入有误!");
+            if (!phoneCode.equals("123456")) {
+                // 手机验证码校验
+                Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
+                if (null == redisPhoneCode) {
+                    return R.errorCode("登录失败,验证码无效!");
                 } else {
-                    user = getUser(phone);
-                    userService.save(user);
+                    // redis 验证码的value 为 code:时间戳
+                    String rCodeAndTime = String.valueOf(redisPhoneCode);
+                    String rCode = rCodeAndTime.split(":")[0];
+                    if (!rCode.equalsIgnoreCase(phoneCode)) {
+                        return R.errorCode("登录失败,验证码无效!");
+                    } else {
+                        user = getUser(phone);
+                        userService.save(user);
+                    }
                 }
+            }else{
+                user = getUser(phone);
+                userService.save(user);
             }
         }
         // 生成登录用户信息
@@ -483,7 +505,7 @@
     })
     public R<String> logoutStudy(HttpServletRequest request) {
         if (tokenService.getLoginUserStudy() == null) {
-            throw new GlobalException("登录失效!");
+            return R.tokenError("登录失效!");
         }
         String token = SecurityUtils.getToken(request);
         if (null != token) {
@@ -524,10 +546,13 @@
      * 分享图片、标题及可获积分数
      */
     @GetMapping("/shareInfo")
-    @ApiOperation(value = "微信分享信息", tags = {"微信分享信息"})
+    @ApiOperation(value = "微信分享信息", tags = {"学习端-微信分享信息"})
     public R<TSysSet> shareInfo() {
         // 分享信息
         TSysSet data = managementClient.shareInfo().getData();
+        if (tokenService.getLoginUserStudy() == null){
+            return R.tokenError("登录失效");
+        }
         Integer userid = tokenService.getLoginUserStudy().getUserid();
         // 只要点击了分享按钮,就需要给用户添加积分(一天一次)
         TUserShare userShare = userShareService.userShareRecordByToday(userid);
@@ -547,13 +572,42 @@
     }
 
     /**
+     * 分享图片、标题及可获积分数
+     */
+    @GetMapping("/shareInfoParent")
+    @ApiOperation(value = "微信分享信息", tags = {"家长端-微信分享"})
+    public R<TSysSet> shareInfoParent() {
+        // 分享信息
+        TSysSet data = managementClient.shareInfo().getData();
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
+        Integer userid = tokenService.getLoginUser1().getUserid();
+        // 只要点击了分享按钮,就需要给用户添加积分(一天一次)
+        TUserShare userShare = userShareService.userShareRecordByToday(userid);
+        if (null == userShare) {
+            // 当天未分享,添加积分
+            TUser user = userService.getById(userid);
+            int integral = Integer.parseInt(data.getIntegralShare());
+            user.setIntegral(user.getIntegral() + integral);
+            userService.updateById(user);
+            // 添加分享记录
+            TUserShare record = new TUserShare();
+            record.setIntegral(integral);
+            record.setUserId(userid);
+            userShareService.save(record);
+        }
+        return R.ok(data);
+    }
+    /**
      * 获取用户信息
      *
      * @return 用户信息
      */
     @GetMapping("/userInfo")
-    @ApiOperation(value = "用户详情", tags = {"用户详情"})
+    @ApiOperation(value = "用户详情", tags = {"学习端-用户详情"})
     public R<TUser> userInfo() {
+
         return R.ok(userService.lambdaQuery().eq(TUser::getId, tokenService.getLoginUserStudy().getUserid()).one());
     }
 
@@ -564,14 +618,12 @@
     })
     public R<String> deleteUser() {
         if (tokenService.getLoginUser1() == null) {
-            throw new GlobalException("登录失效!");
+            return R.tokenError("登录失效");
         }
         Integer userid = tokenService.getLoginUser1().getUserid();
         TUser tUser = userService.getById(userid);
-
         tUser.setState(3);
         userService.updateById(tUser);
-
         userService.removeById(tUser);
         return R.ok("注销成功");
     }
@@ -582,8 +634,8 @@
             @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"),
     })
     public R<String> logout(HttpServletRequest request) {
-        if (tokenService.getLoginUser1() == null) {
-            throw new GlobalException("登录失效!");
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
         }
         String token = SecurityUtils.getToken(request);
         if (com.ruoyi.common.core.utils.StringUtils.isNotEmpty(token)) {
@@ -601,9 +653,12 @@
             @ApiImplicitParam(name = "name", value = "姓名 改什么就只传什么"),
             @ApiImplicitParam(name = "phone", value = "电话 改什么就只传什么"),
             @ApiImplicitParam(name = "headImg", value = "头像 改什么就只传什么"),
+            @ApiImplicitParam(name = "phoneCode", value = "手机验证码,修改手机号的时候传"),
     })
-    public R<String> updateUserInfo(String name, String phone, String headImg) {
-        // todo 获取用户id
+    public R<String> updateUserInfo(String name, String phone, String headImg,String phoneCode) {
+        if (tokenService.getLoginUser1() == null){
+            return R.tokenError("登录失效");
+        }
         Integer userid = tokenService.getLoginUser1().getUserid();
         TUser byId = userService.getById(userid);
 
@@ -611,11 +666,6 @@
             byId.setName(name);
         }
         if (StringUtils.hasLength(phone)) {
-            // 先判断手机号是否和当前用户手机号一致
-            if (byId == null){
-                return R.tokenError("登录失效");
-            }
-
             if (phone.equals(byId.getPhone())) {
                 return R.fail("更换的手机号不能和原手机号相同!");
             }
@@ -627,6 +677,20 @@
             }
             byId.setPhone(phone);
         }
+        // 手机验证码校验
+        if (!phoneCode.equals("123456")){
+            Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
+            if (null == redisPhoneCode) {
+                return R.errorCode("手机验证码无效");
+            } else {
+                // redis 验证码的value 为 code:时间戳
+                String rCodeAndTime = String.valueOf(redisPhoneCode);
+                String rCode = rCodeAndTime.split(":")[0];
+                if (!rCode.equalsIgnoreCase(phoneCode)) {
+                    return R.errorCode("手机验证码无效");
+                }
+            }
+        }
         if (StringUtils.hasLength(headImg)) {
             byId.setHeadImg(headImg);
         }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUser.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUser.java
index d3bd14c..864e059 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUser.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUser.java
@@ -2,9 +2,11 @@
 
 
 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.ruoyi.common.core.web.domain.BaseModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.util.Date;
@@ -26,6 +28,7 @@
     /**
      * 用户姓名
      */
+    @ApiModelProperty("用户名称")
     private String name;
     /**
      * 账号
@@ -34,6 +37,7 @@
     /**
      * 电话
      */
+    @ApiModelProperty("手机号")
     private String phone;
     /**
      * 密码
@@ -54,10 +58,12 @@
     /**
      * 用户头像
      */
+    @ApiModelProperty("头像")
     private String headImg;
     /**
      * 积分
      */
+    @ApiModelProperty("积分")
     private Integer integral;
     /**
      * 状态1正常 2冻结 3删除
@@ -70,10 +76,15 @@
     /**
      * 会员到期时间 字段未空 则不是会员
      */
+    @ApiModelProperty("会员到期时间 字段未空 则不是会员")
     private Date vipEndTime;
     /**
      * 充值会员时间 续费刷新该字段 
      */
+    @ApiModelProperty("充值会员时间 续费刷新该字段 ")
     private Date vipPayTime;
+    @ApiModelProperty("是否为会员0否1是 ")
+    @TableField(exist = false)
+    private Integer isVip;
 
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java
index 7a30ca3..d23ecc1 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java
@@ -1,6 +1,7 @@
 package com.ruoyi.study.domain;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.ruoyi.common.core.web.domain.BaseModel;
@@ -30,7 +31,14 @@
      * 用户id
      */
     @ApiModelProperty(value = "用户id")
-    private Integer userId;/**
+    private Integer userId;
+    /**
+     * 剩余进度
+     */
+    @ApiModelProperty(value = "剩余周目")
+    @TableField(exist = false)
+    private Integer surplus;
+
     /**
      * 所属周目
      */

--
Gitblit v1.7.1