Browse Source

Merge remote-tracking branch 'origin/master'

zx 1 month ago
parent
commit
1911e94622

+ 2 - 0
fs-admin/src/main/java/com/fs/course/controller/FsVideoResourceController.java

@@ -37,6 +37,7 @@ public class FsVideoResourceController extends BaseController {
     public TableDataInfo list(@RequestParam(required = false) String resourceName,
     public TableDataInfo list(@RequestParam(required = false) String resourceName,
                               @RequestParam(required = false) String fileName,
                               @RequestParam(required = false) String fileName,
                               @RequestParam(required = false) Integer typeId,
                               @RequestParam(required = false) Integer typeId,
+                              @RequestParam(required = false) Integer typeSubId,
                               @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                               @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                               @RequestParam(required = false, defaultValue = "10") Integer pageSize)
                               @RequestParam(required = false, defaultValue = "10") Integer pageSize)
     {
     {
@@ -44,6 +45,7 @@ public class FsVideoResourceController extends BaseController {
         params.put("resourceName", resourceName);
         params.put("resourceName", resourceName);
         params.put("fileName", fileName);
         params.put("fileName", fileName);
         params.put("typeId", typeId);
         params.put("typeId", typeId);
+        params.put("typeSubId", typeSubId);
 
 
         PageHelper.startPage(pageNum, pageSize);
         PageHelper.startPage(pageNum, pageSize);
         List<FsVideoResourceVO> list = fsVideoResourceService.selectVideoResourceListByMap(params);
         List<FsVideoResourceVO> list = fsVideoResourceService.selectVideoResourceListByMap(params);

+ 2 - 0
fs-company-app/src/main/java/com/fs/app/annotation/Login.java

@@ -9,4 +9,6 @@ import java.lang.annotation.*;
 @Retention(RetentionPolicy.RUNTIME)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Documented
 public @interface Login {
 public @interface Login {
+    // 添加一个判断 是否是小程序登录
+    boolean isMiniLogin() default false;
 }
 }

+ 37 - 6
fs-company-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java

@@ -5,11 +5,14 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateTime;
+import com.fs.app.annotation.Login;
 import com.fs.app.param.LoginMaWxParam;
 import com.fs.app.param.LoginMaWxParam;
 import com.fs.app.utils.JwtUtils;
 import com.fs.app.utils.JwtUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.IpUtil;
 import com.fs.common.utils.IpUtil;
+import com.fs.common.utils.ServletUtils;
 import com.fs.company.domain.CompanyDept;
 import com.fs.company.domain.CompanyDept;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyDeptService;
 import com.fs.company.service.ICompanyDeptService;
@@ -18,6 +21,7 @@ import com.fs.core.security.SecurityUtils;
 import com.fs.store.service.IFsUserService;
 import com.fs.store.service.IFsUserService;
 import com.fs.wx.miniapp.config.WxMaConfiguration;
 import com.fs.wx.miniapp.config.WxMaConfiguration;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.wx.miniapp.config.WxMaProperties;
+import io.jsonwebtoken.Claims;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -25,10 +29,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 
 import java.util.Date;
 import java.util.Date;
 import java.util.Objects;
 import java.util.Objects;
@@ -45,14 +46,17 @@ public class WxCompanyUserController extends AppBaseController {
     @Autowired
     @Autowired
     JwtUtils jwtUtils;
     JwtUtils jwtUtils;
 
 
+    @Autowired
+    RedisCache redisCache;
+
     @Autowired
     @Autowired
     private ICompanyUserService companyUserService;
     private ICompanyUserService companyUserService;
 
 
     @Autowired
     @Autowired
     private ICompanyDeptService companyDeptService;
     private ICompanyDeptService companyDeptService;
 
 
-    @ApiOperation("授权登录")
-    @PostMapping("/login")
+    @ApiOperation("小程序-销售授权登录")
+    @PostMapping("/loginByMa")
     public R login(@RequestBody LoginMaWxParam param) {
     public R login(@RequestBody LoginMaWxParam param) {
         if (StringUtils.isBlank(param.getCode())) {
         if (StringUtils.isBlank(param.getCode())) {
             return R.error("code不存在");
             return R.error("code不存在");
@@ -126,5 +130,32 @@ public class WxCompanyUserController extends AppBaseController {
         }
         }
     }
     }
 
 
+    @Login(isMiniLogin = true)
+    @ApiOperation("获取销售通过小程序登录后的用户信息")
+    @GetMapping("/getMaUser")
+    public R getUserInfo() {
+        try {
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(Long.parseLong(getUserId()));
+            if (companyUser == null) {
+                return R.error(401, "用户信息不存在");
+            }
+            return R.ok().put("user", companyUser);
+        } catch (Exception e) {
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 特殊要求:销售小程序临时登录,登录后页面中还有一个之前常用的登录,所以为了区分,token名称不能跟之前的一样
+     *
+     * @return 用户id
+     */
+    public String getUserId() {
+        String headValue = ServletUtils.getRequest().getHeader("UserToken");
+        Claims claims = jwtUtils.getClaimByToken(headValue);
+        String userId = claims.getSubject().toString();
+        return userId;
+    }
+
 
 
 }
 }

+ 11 - 6
fs-company-app/src/main/java/com/fs/app/interceptor/AuthorizationInterceptor.java

@@ -6,6 +6,7 @@ import com.fs.app.annotation.Login;
 import com.fs.app.exception.FSException;
 import com.fs.app.exception.FSException;
 import com.fs.app.utils.JwtUtils;
 import com.fs.app.utils.JwtUtils;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.StringUtils;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Claims;
 
 
@@ -43,19 +44,23 @@ public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
         }
         }
 
 
         //获取用户凭证
         //获取用户凭证
-        String token = request.getHeader(jwtUtils.getHeader());
-        if(StringUtils.isBlank(token)){
-            token = request.getParameter(jwtUtils.getHeader());
+        String token;
+        if(!annotation.isMiniLogin()){
+            token = request.getHeader(jwtUtils.getHeader());
+            if(StringUtils.isBlank(token)){
+                token = request.getParameter(jwtUtils.getHeader());
+            }
+        } else {
+            token = ServletUtils.getRequest().getHeader("UserToken");
         }
         }
-
         //凭证为空
         //凭证为空
         if(StringUtils.isBlank(token)){
         if(StringUtils.isBlank(token)){
-            throw new FSException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
+            throw new FSException(annotation.isMiniLogin() ? "UserToken不能为空" : jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
         }
         }
 
 
         Claims claims = jwtUtils.getClaimByToken(token);
         Claims claims = jwtUtils.getClaimByToken(token);
         if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
         if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
-            throw new FSException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
+            throw new FSException(annotation.isMiniLogin() ? "UserToken失效,请重新登录" : jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
         }
         }
 //        //查询用户的TOKEN是否和REDIS中的一样
 //        //查询用户的TOKEN是否和REDIS中的一样
 //        String redisToken=redisCache.getCacheObject("token:"+ Long.parseLong(claims.getSubject()));
 //        String redisToken=redisCache.getCacheObject("token:"+ Long.parseLong(claims.getSubject()));

+ 1 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsCourseQuestionBank.java

@@ -42,4 +42,5 @@ public class FsCourseQuestionBank extends BaseEntity
     @Excel(name = "答案")
     @Excel(name = "答案")
     private String answer;
     private String answer;
     private Long questionType;
     private Long questionType;
+    private Long questionSubType;
 }
 }

+ 5 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsVideoResource.java

@@ -27,6 +27,11 @@ public class FsVideoResource {
      */
      */
     private Long typeId;
     private Long typeId;
 
 
+    /**
+     * 子分类ID
+     */
+    private Long typeSubId;
+
     /**
     /**
      * 文件名称
      * 文件名称
      */
      */

+ 2 - 2
fs-service-system/src/main/java/com/fs/course/vo/FsVideoResourceVO.java

@@ -23,9 +23,9 @@ public class FsVideoResourceVO {
     private Long typeId;
     private Long typeId;
 
 
     /**
     /**
-     * 分类名称
+     * 子分类ID
      */
      */
-    private String typeName;
+    private Long typeSubId;
 
 
     /**
     /**
      * 文件名称
      * 文件名称

+ 35 - 0
fs-service-system/src/main/java/com/fs/statis/dto/DealerAggregatedDTO.java

@@ -32,4 +32,39 @@ public class DealerAggregatedDTO implements Serializable {
      */
      */
     private Long qwMemberNum;
     private Long qwMemberNum;
 
 
+    /**
+     * 今日新增
+     */
+    private Long todayIncreaseUserNum;
+
+    /**
+     * 订单总数
+     */
+    private Long orderTotalNum;
+
+    /**
+     * 今日新增订单数
+     */
+    private Long todayOrderNum;
+
+    /**
+     * 收款总数
+     */
+    private Long recvTotalNum;
+
+    /**
+     * 今日收款总数
+     */
+    private Long recvTodayNum;
+
+    /**
+     * 商品总数
+     */
+    private Long goodsTotalNum;
+
+    /**
+     * 今日商品总数
+     */
+    private Long todayGoodsNum;
+
 }
 }

+ 31 - 1
fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsServiceImpl.java

@@ -8,6 +8,10 @@ import com.fs.statis.dto.*;
 import com.fs.statis.mapper.ConsumptionBalanceMapper;
 import com.fs.statis.mapper.ConsumptionBalanceMapper;
 import com.fs.statis.service.IStatisticsService;
 import com.fs.statis.service.IStatisticsService;
 import com.fs.statis.service.utils.TrendDataFiller;
 import com.fs.statis.service.utils.TrendDataFiller;
+import com.fs.store.service.IFsStoreOrderService;
+import com.fs.store.service.IFsStorePaymentService;
+import com.fs.store.service.IFsStoreProductService;
+import com.fs.store.service.IFsUserService;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.hc.openapi.tool.util.ObjectUtils;
 import com.hc.openapi.tool.util.ObjectUtils;
 import com.hc.openapi.tool.util.StringUtils;
 import com.hc.openapi.tool.util.StringUtils;
@@ -41,7 +45,17 @@ public class StatisticsServiceImpl implements IStatisticsService {
 
 
     @Autowired
     @Autowired
     private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;
     private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;
+    @Autowired
+    private IFsUserService userService;
+
+    @Autowired
+    private IFsStoreOrderService storeOrderService;
 
 
+    @Autowired
+    private IFsStorePaymentService paymentService;
+
+    @Autowired
+    private IFsStoreProductService productService;
 
 
     @Override
     @Override
     public void dataOverviewTask() {
     public void dataOverviewTask() {
@@ -559,9 +573,25 @@ public class StatisticsServiceImpl implements IStatisticsService {
     }
     }
 
 
 
 
+
     @Override
     @Override
     public DealerAggregatedDTO dealerAggregated() {
     public DealerAggregatedDTO dealerAggregated() {
-        return consumptionBalanceMapper.dealerAggregated();
+        Long dayUserCount=userService.selectFsUserCount(1,null);
+        Long storeOrderCount=storeOrderService.selectFsStoreOrderTotalCount(0,null);
+        Long dayStoreOrderCount=storeOrderService.selectFsStoreOrderTotalCount(1,null);
+        Long paymentCount=paymentService.selectFsStorePaymentCount(0,null);
+        Long dayPaymentCount=paymentService.selectFsStorePaymentCount(1,null);
+        Long productCount=productService.selectFsStoreProductCount(0);
+        Long dayProductCount=productService.selectFsStoreProductCount(1);
+        DealerAggregatedDTO dealerAggregatedDTO = consumptionBalanceMapper.dealerAggregated();
+        dealerAggregatedDTO.setTodayIncreaseUserNum(dayUserCount);
+        dealerAggregatedDTO.setOrderTotalNum(storeOrderCount);
+        dealerAggregatedDTO.setTodayOrderNum(dayStoreOrderCount);
+        dealerAggregatedDTO.setRecvTodayNum(paymentCount);
+        dealerAggregatedDTO.setRecvTodayNum(dayPaymentCount);
+        dealerAggregatedDTO.setGoodsTotalNum(productCount);
+        dealerAggregatedDTO.setTodayGoodsNum(dayProductCount);
+        return dealerAggregatedDTO;
     }
     }
 
 
     @Override
     @Override

+ 66 - 0
fs-service-system/src/main/resources/db/upgrade/20250428.sql

@@ -0,0 +1,66 @@
+DROP PROCEDURE IF EXISTS add_tb_column;
+DELIMITER $$
+CREATE PROCEDURE add_tb_column()
+BEGIN
+		DECLARE  CurrentDatabase VARCHAR(100);
+SELECT DATABASE() INTO CurrentDatabase;
+
+-- fs_user_course_video_red_package 表添加 period_id 字段
+IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS  WHERE TABLE_SCHEMA=CurrentDatabase
+            AND TABLE_NAME='fs_user_course_video_red_package'
+            AND COLUMN_NAME='period_id' )
+		THEN
+            alter table fs_user_course_video_red_package add column period_id bigint COMMENT '营期id';
+        END IF;
+
+-- fs_user_course_video_red_package 表添加 data_type 字段
+IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS  WHERE TABLE_SCHEMA=CurrentDatabase
+				AND TABLE_NAME='fs_user_course_video_red_package'
+				AND COLUMN_NAME='data_type' )
+		THEN
+            alter table fs_user_course_video_red_package add column data_type int COMMENT '类型,1-课程;2-营期;3-sop模板';
+        END IF;
+
+-- company 表添加 fs_user_is_default_black 字段
+IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS  WHERE TABLE_SCHEMA=CurrentDatabase
+				AND TABLE_NAME='company'
+				AND COLUMN_NAME='fs_user_is_default_black')
+		THEN
+            alter table company add column fs_user_is_default_black tinyint(1) COMMENT '会员是否默认黑名单,1-是;0-否(用于销售分享成为会员的操作)';
+        END IF;
+
+-- company_user 表添加 ma_open_id 字段
+IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS  WHERE TABLE_SCHEMA=CurrentDatabase
+				AND TABLE_NAME='company_user'
+				AND COLUMN_NAME='ma_open_id')
+		THEN
+            alter table company_user add column ma_open_id varchar(50) COMMENT '微信小程序OPENID(如果有小程序授权)';
+        END IF;
+
+--  修改统计表字段
+IF EXISTS (SELECT 1 FROM information_schema.COLUMNS  WHERE TABLE_SCHEMA=CurrentDatabase
+				AND TABLE_NAME='fs_user_course_count'
+				AND COLUMN_NAME='course_id')
+		THEN
+            alter table fs_user_course_count change course_id course_ids VARCHAR(500) COMMENT '关联课程(营期)id';
+        END IF;
+
+--  添加 fs_course_watch_log 表的索引,字段为 period_id
+IF NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = CurrentDatabase
+                AND TABLE_NAME = 'fs_course_watch_log'
+                AND INDEX_NAME = 'idx_period_id' )
+        THEN
+            alter table fs_course_watch_log ADD INDEX idx_period_id ( `period_id` ASC );
+        END IF;
+
+--  添加 fs_course_answer_logs 表的索引,字段为 period_id
+IF NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = CurrentDatabase
+                AND TABLE_NAME = 'fs_course_answer_logs'
+                AND INDEX_NAME = 'idx_period_id' )
+        THEN
+ALTER TABLE fs_course_answer_logs ADD INDEX idx_period_id(`period_id` ASC);
+END IF;
+
+END;
+
+CALL add_tb_column;

+ 6 - 1
fs-service-system/src/main/resources/mapper/course/FsCourseQuestionBankMapper.xml

@@ -15,10 +15,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="answer"    column="answer"    />
         <result property="answer"    column="answer"    />
         <result property="createBy"    column="create_by"    />
         <result property="createBy"    column="create_by"    />
         <result property="questionType"    column="question_type"    />
         <result property="questionType"    column="question_type"    />
+        <result property="questionSubType"    column="question_sub_type"    />
     </resultMap>
     </resultMap>
 
 
     <sql id="selectFsCourseQuestionBankVo">
     <sql id="selectFsCourseQuestionBankVo">
-        select id, title, sort, type, status,question_type, question, create_time, answer, create_by from fs_course_question_bank
+        select id, title, sort, type, status,question_type, question_sub_type, question, create_time, answer, create_by from fs_course_question_bank
     </sql>
     </sql>
 
 
     <select id="selectFsCourseQuestionBankList" parameterType="FsCourseQuestionBank" resultMap="FsCourseQuestionBankResult">
     <select id="selectFsCourseQuestionBankList" parameterType="FsCourseQuestionBank" resultMap="FsCourseQuestionBankResult">
@@ -28,6 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="sort != null "> and sort = #{sort}</if>
             <if test="sort != null "> and sort = #{sort}</if>
             <if test="type != null "> and type = #{type}</if>
             <if test="type != null "> and type = #{type}</if>
             <if test="questionType != null "> and question_type = #{questionType}</if>
             <if test="questionType != null "> and question_type = #{questionType}</if>
+            <if test="questionSubType != null "> and question_sub_type = #{questionSubType}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="question != null  and question != ''"> and question = #{question}</if>
             <if test="question != null  and question != ''"> and question = #{question}</if>
             <if test="answer != null  and answer != ''"> and answer = #{answer}</if>
             <if test="answer != null  and answer != ''"> and answer = #{answer}</if>
@@ -52,6 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="answer != null">answer,</if>
             <if test="answer != null">answer,</if>
             <if test="createBy != null">create_by,</if>
             <if test="createBy != null">create_by,</if>
             <if test="questionType != null">question_type,</if>
             <if test="questionType != null">question_type,</if>
+            <if test="questionSubType != null">question_sub_type,</if>
          </trim>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="title != null">#{title},</if>
             <if test="title != null">#{title},</if>
@@ -63,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="answer != null">#{answer},</if>
             <if test="answer != null">#{answer},</if>
             <if test="createBy != null">#{createBy},</if>
             <if test="createBy != null">#{createBy},</if>
             <if test="questionType != null">#{questionType},</if>
             <if test="questionType != null">#{questionType},</if>
+            <if test="questionSubType != null">#{questionSubType},</if>
          </trim>
          </trim>
     </insert>
     </insert>
 
 
@@ -78,6 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="answer != null">answer = #{answer},</if>
             <if test="answer != null">answer = #{answer},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
             <if test="questionType != null">question_type = #{questionType},</if>
             <if test="questionType != null">question_type = #{questionType},</if>
+            <if test="questionSubType != null">question_sub_type = #{questionSubType},</if>
         </trim>
         </trim>
         where id = #{id}
         where id = #{id}
     </update>
     </update>

+ 4 - 3
fs-service-system/src/main/resources/mapper/course/FsVideoResourceMapper.xml

@@ -6,10 +6,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
 
     <select id="selectVideoResourceListByMap" resultType="com.fs.course.vo.FsVideoResourceVO">
     <select id="selectVideoResourceListByMap" resultType="com.fs.course.vo.FsVideoResourceVO">
         select
         select
-            rr.*,
-            ucc.cate_name typeName
+            rr.*
         from fs_video_resource rr
         from fs_video_resource rr
-        left join fs_user_course_category ucc on ucc.cate_id = rr.type_id
         where rr.is_del = 0
         where rr.is_del = 0
         <if test="params.resourceName != null and params.resourceName != ''">
         <if test="params.resourceName != null and params.resourceName != ''">
             and rr.resource_name like concat('%', #{params.resourceName}, '%')
             and rr.resource_name like concat('%', #{params.resourceName}, '%')
@@ -20,6 +18,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="params.typeId != null">
         <if test="params.typeId != null">
             and rr.type_id = #{params.typeId}
             and rr.type_id = #{params.typeId}
         </if>
         </if>
+        <if test="params.typeSubId != null">
+            and rr.type_sub_id = #{params.typeSubId}
+        </if>
         order by rr.create_time desc
         order by rr.create_time desc
     </select>
     </select>
 </mapper>
 </mapper>