Ver código fonte

会员调整

yuanliang 1 ano atrás
pai
commit
41f094a0a4

+ 0 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/StudentDao.java

@@ -83,5 +83,4 @@ public interface StudentDao extends BaseMapper<Student> {
 
     List<StudentWrapper.UserCount> countStudentByTenantGroupIds(@Param("tenantId") Long tenantId, @Param("groupIdList") List<Long> groupIdList);
 
-    List<StudentWrapper.StudentVipInfo> queryStudentVipInfo(@Param("studentIdList") List<Long> studentIdList);
 }

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/VipCardRecordDao.java

@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
 import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import org.apache.ibatis.annotations.Param;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
@@ -58,4 +60,6 @@ public interface VipCardRecordDao extends BaseMapper<VipCardRecord> {
      * @return
      */
     IPage<VipRecordVo> selectVipRecord(@Param("page") IPage<VipRecordVo> page, @Param("param") VipRecordSearch param);
+
+    List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(@Param("userIdList") List<Long> userIdList ,@Param("clientType") String clientType);
 }

+ 0 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java

@@ -15,7 +15,6 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
-import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -135,5 +134,4 @@ public interface StudentService extends IService<Student> {
 
     Map<Long,Student> getMapByIds(List<Long> userIds);
 
-    List<StudentWrapper.StudentVipInfo> queryStudentVipInfo( List<Long> studentIdList);
 }

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VipCardRecordService.java

@@ -19,6 +19,7 @@ import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.base.page.PageInfo;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -120,4 +121,6 @@ public interface VipCardRecordService extends IService<VipCardRecord> {
 
     // 会员添加
     VipCardRecord addVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord);
+
+    List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(List<Long> userIdList , String clientType);
 }

+ 5 - 17
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java

@@ -46,7 +46,6 @@ import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import com.yonge.toolset.utils.string.ValueUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.annotations.Param;
 import org.redisson.api.RMap;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.BeanUtils;
@@ -140,17 +139,11 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         VipCardRecordWrapper.UserVip userVip = vipCardRecordService.UserVipInfo(userId, ClientEnum.STUDENT);
         detail.setUserVip(userVip);
         detail.setVipType(EUserVipType.NORMAL);
-        if (userVip != null) {
-            Date svipEndDate = userVip.getSvipEndDate();
-            Date vipEndDate = userVip.getVipEndDate();
-            if (svipEndDate != null && svipEndDate.after(new Date())) {
-                detail.setVipType(EUserVipType.SVIP);
-                detail.setMembershipEndTime(userVip.getSvipEndDate());
-            } else if (vipEndDate != null && vipEndDate.after(new Date())) {
-                detail.setVipType(EUserVipType.VIP);
-                detail.setMembershipEndTime(userVip.getVipEndDate());
-            }
-        }
+        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.STUDENT.getCode());
+        Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
+        VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
+        detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
+        detail.setVipType(vipType.getCurrentVipType());
         return detail;
     }
 
@@ -685,11 +678,6 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
 
     }
 
-    @Override
-    public List<StudentWrapper.StudentVipInfo> queryStudentVipInfo(List<Long> studentIdList) {
-        return baseMapper.queryStudentVipInfo(studentIdList);
-    }
-
     private Boolean updateStudent(StudentWrapper.Student studentInfo) {
         StudentVo student = detail(studentInfo.getId());
         if (student == null) {

+ 9 - 23
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java

@@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
-import com.microsvc.toolkit.middleware.rtc.enums.EDeviceMessageType;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -49,12 +48,9 @@ import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindHistoryMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
-import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.HotTeacherVo;
-import com.yonge.cooleshow.biz.dal.vo.MusicSheetUploadCountVo;
 import com.yonge.cooleshow.biz.dal.vo.MyFens;
-import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
@@ -62,10 +58,9 @@ import com.yonge.cooleshow.biz.dal.wordfilter.WordFilter;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
@@ -93,21 +88,12 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
 import org.apache.commons.lang3.StringUtils;
-import org.redisson.api.RMap;
-import org.redisson.api.RedissonClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
@@ -115,11 +101,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
 
 @Service
 public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {
@@ -251,6 +232,11 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
         // 会员信息
         detail.setUserVip(vipCardRecordService.UserVipInfo(detail.getUserId(), ClientEnum.TEACHER));
+        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.TEACHER.getCode());
+        Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
+        VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
+        detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
+        detail.setVipType(vipType.getCurrentVipType());
         return detail;
     }
 
@@ -950,8 +936,8 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                 TeacherQueryInfo.FansQuery.builder().teacherId(teacherId).build());
         if (!teacherVos.isEmpty()) {
             List<Long> studentIds = teacherVos.stream().map(n -> Long.valueOf(n.getUserId())).collect(Collectors.toList());
-            Map<Long, EUserVipType> vipMap = studentService.queryStudentVipInfo(studentIds).stream()
-                    .collect(Collectors.toMap(StudentWrapper.StudentVipInfo::getStudentId, StudentWrapper.StudentVipInfo::getCurrentVipType));
+            Map<Long, EUserVipType> vipMap = vipCardRecordService.queryUserVipInfo(studentIds,ClientEnum.STUDENT.getCode()).stream()
+                    .collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, VipCardRecordWrapper.UserVipInfo::getCurrentVipType));
 
             for (MyFens teacherVo : teacherVos) {
                 EUserVipType vipType = vipMap.getOrDefault(Long.valueOf(teacherVo.getUserId()), EUserVipType.NORMAL);

+ 9 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserBindingTeacherServiceImpl.java

@@ -11,6 +11,7 @@ import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.StudentAttendance;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.biz.dal.enums.StudentCourseEnum;
@@ -18,9 +19,11 @@ import com.yonge.cooleshow.biz.dal.queryInfo.TeacherBindingUserQueryInfo;
 import com.yonge.cooleshow.biz.dal.service.StudentAttendanceService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.UserBindingTeacherService;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
 import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingCourseWrapper;
 import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingTeacherWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
@@ -36,7 +39,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -66,6 +68,9 @@ public class UserBindingTeacherServiceImpl extends ServiceImpl<UserBindingTeache
     @Autowired
     private StudentAttendanceService studentAttendanceService;
 
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
     @Override
     public void unbindTask() {
         String days = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_UNBIND_DAYS);
@@ -107,8 +112,9 @@ public class UserBindingTeacherServiceImpl extends ServiceImpl<UserBindingTeache
         // vip
         List<Student> students = studentDao.selectBatchIds(studentIdList);
 
-        List<StudentWrapper.StudentVipInfo> studentVipInfoList = studentDao.queryStudentVipInfo(studentIdList);
-        Map<Long, EUserVipType> vipMap = studentVipInfoList.stream().collect(Collectors.toMap(StudentWrapper.StudentVipInfo::getStudentId, StudentWrapper.StudentVipInfo::getCurrentVipType));
+        List<VipCardRecordWrapper.UserVipInfo> studentVipInfoList = vipCardRecordService.queryUserVipInfo(studentIdList, ClientEnum.STUDENT.getCode());
+        Map<Long, EUserVipType> vipMap = studentVipInfoList.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId,
+                VipCardRecordWrapper.UserVipInfo::getCurrentVipType));
 
 //        Map<Long, YesOrNoEnum> userIdVipMap = students.stream()
 //                                                      .collect(Collectors.toMap(Student::getUserId,

+ 10 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VipCardRecordServiceImpl.java

@@ -261,8 +261,6 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
             .in(VipCardRecord::getVipType, Lists.newArrayList(EVipType.VIP,EVipType.SVIP))
             .and(wrapper -> wrapper
                 .gt(VipCardRecord::getEndTime, new Date())
-                .or()
-                .isNull(VipCardRecord::getEndTime)
             )
             .list();
     }
@@ -536,6 +534,11 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         return newRecord;
     }
 
+    @Override
+    public List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(List<Long> userIdList, String clientType) {
+        return baseMapper.queryUserVipInfo(userIdList, clientType);
+    }
+
 
     // 会员扣减
     private VipCardRecord deductVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
@@ -601,12 +604,17 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         List<VipCardRecord> updateRecords = new ArrayList<>();
         Long deductMills = null;
 
+        EVipType vipType = addVipCardRecord.getVipType();
         for (VipCardRecord vipCardRecord : vipCardRecordList) {
             Date startTime = vipCardRecord.getStartTime();
             Date endTime = vipCardRecord.getEndTime();
             if (endTime.before(deductedStartDate) || endTime.equals(deductedStartDate)) {
                 continue;
             }
+            // 扣减vip,跳过SVIP
+            if (EVipType.VIP.equals(vipType) && EVipType.SVIP.equals(vipCardRecord.getVipType())) {
+                continue;
+            }
 
             Long addId = null;
             // 扣减到当前时间区间

+ 0 - 12
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StudentWrapper.java

@@ -3,7 +3,6 @@ package com.yonge.cooleshow.biz.dal.wrapper;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
-import com.yonge.cooleshow.biz.dal.enums.EVipType;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
@@ -14,7 +13,6 @@ import org.apache.commons.lang3.StringUtils;
 
 import javax.validation.constraints.NotNull;
 import java.io.Serializable;
-import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
@@ -232,14 +230,4 @@ public class StudentWrapper {
         private Long tenantGroupId;
         private Integer count;
     }
-
-
-    @Data
-    public static class StudentVipInfo {
-
-        private Long studentId;
-
-        private EUserVipType currentVipType;
-
-    }
 }

+ 37 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/VipCardRecordWrapper.java

@@ -10,6 +10,7 @@ import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
 import java.util.Date;
+import java.util.Optional;
 
 public class VipCardRecordWrapper {
 
@@ -91,4 +92,40 @@ public class VipCardRecordWrapper {
         private Long vipCardId;
         private String subOrderNo;
     }
+
+    @Data
+    public static class UserVipInfo {
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("当前会员类型")
+        private EUserVipType currentVipType;
+
+        @ApiModelProperty("VIP的结束时间")
+        private Date currentVipSvipEndTime;
+
+        @ApiModelProperty("vip结束时间")
+        private Date vipEndTime;
+
+        @ApiModelProperty("svip结束时间")
+        private Date svipEndTime;
+
+        @ApiModelProperty("svip结束时间")
+        private Date perSvipEndTime;
+
+        public Date getCurrentVipSvipEndTime() {
+            if (EUserVipType.NORMAL.equals(currentVipType)) {
+                return Optional.ofNullable(vipEndTime).orElse(svipEndTime);
+            } else if (EUserVipType.VIP.equals(currentVipType)) {
+                return vipEndTime;
+            } else {
+                if (perSvipEndTime != null) { // 永久SVIP
+                    return null;
+                } else {
+                    return svipEndTime;
+                }
+            }
+        }
+    }
 }

+ 0 - 11
cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml

@@ -394,15 +394,4 @@
         </where>
         group by tenant_group_id_
     </select>
-
-    <select id="queryStudentVipInfo" resultType="com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper$StudentVipInfo">
-        select t.user_id_ studentId
-        ,ifnull(vcr.vip_type_,'NORMAL') currentVipType
-        from student t
-        left join vip_card_record vcr on t.user_id_ = vcr.user_id_ and vcr.efficient_flag_ = 1 and vcr.end_time_>now() and now()>= vcr.start_time_ and vcr.client_type_= 'STUDENT'
-        where t.user_id_ in
-        <foreach collection="param.studentIdList" separator="," item="item" open="(" close=")">
-            #{item}
-        </foreach>
-    </select>
 </mapper>

+ 19 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/VipCardRecordMapper.xml

@@ -83,7 +83,7 @@
         from (
             select any_value(id_) id_
             from (
-            select id_ from vip_card_record where efficient_flag_ = 1 and end_time_ &gt;= now() and end_time_ &lt; DATE_ADD(now(),INTERVAL 3 DAY) order by end_time_ desc
+            select * from vip_card_record where efficient_flag_ = 1 and end_time_ &gt;= now() and end_time_ &lt; DATE_ADD(now(),INTERVAL 3 DAY) order by end_time_ desc
             ) t group by t.user_id_,t.client_type_,t.vip_type_
         ) a
         left join vip_card_record t on a.id_ = t.id_
@@ -99,7 +99,7 @@
         from (
             select any_value(id_) id_
             from (
-            select id_ from vip_card_record where efficient_flag_ = 1 order by end_time_ desc
+            select * from vip_card_record where efficient_flag_ = 1 order by end_time_ desc
             ) t group by t.user_id_,t.client_type_,t.vip_type_
         ) a
         left join vip_card_record t on a.id_ = t.id_
@@ -144,4 +144,21 @@
       </where>
         order by  t.id_ desc
     </select>
+
+    <select id="queryUserVipInfo" resultType="com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper$UserVipInfo">
+        select t.user_id_ userId
+        ,ifnull(vcr.vip_type_,'NORMAL') currentVipType
+        ,max(if(t.vip_type_ = 'VIP', t.end_time_, null)) vipEndTime
+        ,max(if(t.vip_type_ = 'SVIP' and t.type_ = 'PERPETUAL', t.end_time_ , null)) perSvipEndTime
+        ,max(if(t.vip_type_ = 'SVIP' , t.end_time_, null)) svipEndTime
+        from vip_card_record t
+        left join vip_card_record vcr on t.id_ = vcr.id_ and vcr.end_time_>now() and now()>= vcr.start_time_
+        where t.user_id_ in
+        <foreach collection="userIdList" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and t.client_type_ = #{clientType}
+        and t.efficient_flag_ = 1
+        group by t.user_id_
+    </select>
 </mapper>