Browse Source

Merge remote-tracking branch 'origin/feature/0721-tenant' into feature/0721-tenant

# Conflicts:
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java
#	cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumController.java
haonan 1 year ago
parent
commit
ede05ce3f8

+ 10 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantActivationCodeService.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
@@ -58,4 +59,13 @@ public interface TenantActivationCodeService extends IService<TenantActivationCo
      * @param userOrderDetailVo 订单详情
      */
     void addUserTenantAlbumRecord(Long studentId, UserOrderDetailVo userOrderDetailVo);
+
+    /**
+     * 导入激活码
+     * @param dataList 数据列表
+     * @param tenantId 机构ID
+     * @param id 机构管理员用户ID
+     */
+    void importActiveCode(List<ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate>> dataList,
+                          Long tenantId, Long userId);
 }

+ 2 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java

@@ -7,8 +7,6 @@ import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 
-import java.util.List;
-
 /**
  * 机构专辑
  * 2023-07-21 17:32:49
@@ -20,7 +18,7 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @param id 详情ID
      * @return TenantAlbum
      */
-    TenantAlbum detail(Long id);
+	TenantAlbum detail(Long id);
 
     /**
      * 分页查询
@@ -28,7 +26,7 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @param query TenantAlbumWrapper.TenantAlbumQuery
      * @return IPage<TenantAlbum>
      */
-    IPage<TenantAlbumWrapper.TenantAlbum> selectPage(IPage<TenantAlbumWrapper.TenantAlbum> page, TenantAlbumWrapper.TenantAlbumQuery query);
+    IPage<TenantAlbumWrapper.TenantAlbumQuery> selectPage(IPage<TenantAlbumWrapper.TenantAlbumQuery> page, TenantAlbumWrapper.TenantAlbumQuery query);
 	
     /**
      * 添加

+ 83 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantActivationCodeServiceImpl.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
@@ -15,20 +16,27 @@ import com.yonge.cooleshow.biz.dal.mapper.UserTenantAlbumRecordMapper;
 import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.common.enums.EActivationCode;
 import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Comparator;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -193,7 +201,7 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
         Integer purchaseCycle = purchase.getPurchaseCycle();
 
 
-        addUserTenantAlbumRecord(student.getUserId(), purchase,null);
+        addUserTenantAlbumRecord(student.getUserId(), purchase, null);
 
         // 更新购买记录中激活码使用统计数量值
         Integer activeCodeNumber = this.lambdaQuery()
@@ -211,7 +219,7 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
     /**
      * 添加用户机构专辑激活记录
      *
-     * @param studentId 学生ID
+     * @param studentId         学生ID
      * @param userOrderDetailVo 订单详情
      */
     @Override
@@ -221,7 +229,79 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
 
     }
 
-    private void addUserTenantAlbumRecord(Long studentId, TenantAlbumPurchase purchase, UserOrderDetailVo userOrderDetailVo) {
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void importActiveCode(List<ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate>> dataList,
+                                 Long tenantId, Long userId) {
+        if (dataList.isEmpty()) {
+            return;
+        }
+        dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
+
+        List<String> errMsg = new ArrayList<>();
+        Set<String> codeSet = new HashSet<>();
+        Map<String, Integer> codeRowMap = new HashMap<>();
+        // 校验数据格式是否错误
+        for (ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate> next : dataList) {
+            Integer rowIndex = next.getRowIndex();
+            TenantActivationCodeWrapper.ImportTemplate code = next.getClazz();
+
+            int msgRowNo = rowIndex + 1;
+            code.checkIsIllegal().forEach(err -> errMsg.add(String.format("第%s行%s", msgRowNo, err)));
+            if (codeSet.contains(code.getCode())) {
+                errMsg.add(String.format("第%s行%s", msgRowNo, "激活码重复"));
+            } else {
+                codeSet.add(code.getCode());
+            }
+            codeRowMap.put(code.getCode().trim(), msgRowNo);
+
+            if (errMsg.size() > 100) {
+                break;
+            }
+        }
+
+        if (!errMsg.isEmpty()) {
+            throw new BizException(String.join(",", errMsg));
+        }
+        // 校验激活码是否被使用
+        List<List<String>> codePartition = Lists.partition(new ArrayList<>(codeRowMap.keySet()), 50);
+        for (List<String> codes : codePartition) {
+            List<TenantActivationCode> activationCodes = this.lambdaQuery()
+                    .eq(TenantActivationCode::getTenantId,tenantId)
+                    .in(TenantActivationCode::getActivationCode, codes).list();
+
+            // 存在无效码或者已经使用过的码
+            if (codes.size() != activationCodes.size() ||
+                    activationCodes.stream().anyMatch(TenantActivationCode::getActivationStatus)) {
+                Map<String, Boolean> codeStatusMap = activationCodes.stream()
+                        .collect(Collectors.toMap(TenantActivationCode::getActivationCode,
+                                TenantActivationCode::getActivationStatus));
+                for (String code : codes) {
+                    if (!codeStatusMap.containsKey(code)) {
+                        errMsg.add(String.format("第%s行%s", codeRowMap.get(code), "验证码无效"));
+                    } else if (Boolean.TRUE.equals(codeStatusMap.get(code))) {
+                        errMsg.add(String.format("第%s行%s", codeRowMap.get(code), "验证码已经激活"));
+                    }
+                }
+            }
+        }
+        if (!errMsg.isEmpty()) {
+            throw new BizException(String.join(",", errMsg));
+        }
+
+        for (List<String> codes : codePartition) {
+//            this.lambdaUpdate()
+//                    .set(TenantActivationCode::getSendStatus,EActivationCode.SEND)
+//                    .set(TenantActivationCode::getActivationStatus,true)
+//                    .set(TenantActivationCode)
+
+        }
+
+
+    }
+
+    private void addUserTenantAlbumRecord(Long studentId, TenantAlbumPurchase purchase,
+                                          UserOrderDetailVo userOrderDetailVo) {
 
 
         UserTenantAlbumRecord userTenantAlbumRecord = new UserTenantAlbumRecord();
@@ -253,7 +333,6 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
         }
 
 
-
         QueryWrapper<UserTenantAlbumRecord> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda()
                 .eq(UserTenantAlbumRecord::getTenantId, userTenantAlbumRecord.getTenantId())

+ 32 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantActivationCodeWrapper.java

@@ -1,12 +1,16 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.alibaba.fastjson.JSON;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.Optional;
+import java.util.regex.Pattern;
 
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -126,4 +130,32 @@ public class TenantActivationCodeWrapper {
         }
     }
 
+    @Data
+    public static class ImportTemplate {
+
+        @ExcelProperty(value = "激活码")
+        private String code;
+
+        @ExcelProperty(value = "手机号")
+        private String phone;
+
+        private static final String PHONE_REG = "^(13\\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\\d|19[0-35-9])" +
+                "\\d{8}$";
+
+        public List<String> checkIsIllegal() {
+            List<String> errMsg = new ArrayList<>();
+            if (StringUtils.isEmpty(code)) {
+                errMsg.add("激活码不能为空");
+            }
+            if (StringUtils.isEmpty(phone)) {
+                errMsg.add("手机号不能为空");
+            } else if (!Pattern.matches(PHONE_REG, phone)) {
+                errMsg.add("手机号格式错误");
+            }
+            return errMsg;
+        }
+
+
+    }
+
 }

+ 3 - 2
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java

@@ -113,10 +113,11 @@ public class StudentController extends BaseController {
         try {
             ExcelDataReader<StudentWrapper.StudentExport> reader =
                     ExcelUtils.getReader(StudentWrapper.StudentExport.class, file);
-            studentService.importStudentExcel(reader.getDataList(),user.getTenantId(), user.getId());
+            studentService.importStudentExcel(reader.getDataList(), user.getTenantId(), user.getId());
             return HttpResponseResult.succeed();
         } catch (ExcelException e) {
-            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(), BizHttpStatus.IMPORT.getMsg());
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(),
+                    BizHttpStatus.IMPORT.getMsg());
         }
     }
 

+ 89 - 0
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantActivationCodeController.java

@@ -12,26 +12,51 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
 import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.BizHttpStatus;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.tenant.vo.TenantActivationCodeVo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.easyexcel.ErrMsg;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
+import com.yonge.toolset.utils.easyexcel.ExcelException;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import com.yonge.toolset.utils.excel.POIUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 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.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
 
 
 @Slf4j
@@ -53,6 +78,9 @@ public class TenantActivationCodeController extends BaseController {
     @Autowired
     private TenantInfoService tenantInfoService;
 
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
     @ApiOperation(value = "详情", notes = "机构激活码-根据详情ID查询单条, 传入id")
 //    @GetMapping("/detail/{id}")
     public R<TenantActivationCodeVo.TenantActivationCode> detail(@PathVariable("id") Long id) {
@@ -95,6 +123,67 @@ public class TenantActivationCodeController extends BaseController {
         return succeed();
     }
 
+    @GetMapping("/exportActiveCode")
+    @ApiOperation(value = "导出模板")
+    public void exportActiveCode(HttpServletResponse response) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        Long tenantId = sysUser.getTenantId();
+
+        TenantActivationCodeWrapper.TenantActivationCodeQuery query =
+                new TenantActivationCodeWrapper.TenantActivationCodeQuery();
+        query.setTenantId(tenantId);
+        query.setActivationStatus(false);
+        query.setPage(1);
+        query.setRows(9999);
+        IPage<TenantActivationCodeWrapper.TenantActivationCode> queryInfo =
+                tenantActivationCodeService.selectPage(QueryInfo.getPage(query), query);
+        List<TenantActivationCodeWrapper.TenantActivationCode> rows = queryInfo.getRecords();
+        if (rows.isEmpty()) {
+            throw new BizException("没有可导出数据");
+        }
+
+        try (OutputStream outputStream = response.getOutputStream()) {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"激活码", "手机号"}, new String[]{
+                    "activationCode", "activationPhone"}, rows);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=active_code-" + DateUtil.getDate(new Date()) + ".xls");
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            log.error("导出激活码异常", e);
+        }
+    }
+
+    @PostMapping("/importActiveCode")
+    @ApiOperation(value = "导入", notes = "传入file")
+    public HttpResponseResult<List<ErrMsg>> importActiveCode(@RequestParam("file") MultipartFile file) {
+        if (null == file) {
+            return HttpResponseResult.failed("请上传文件");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        TenantStaff tenantStaff = tenantStaffService.getByUserId(user.getId());
+        if (tenantStaff == null) {
+            return HttpResponseResult.failed("权限不足");
+        }
+
+        try {
+            ExcelDataReader<TenantActivationCodeWrapper.ImportTemplate> reader =
+                    ExcelUtils.getReader(TenantActivationCodeWrapper.ImportTemplate.class, file);
+            tenantActivationCodeService.importActiveCode(reader.getDataList(), user.getTenantId(), user.getId());
+            return HttpResponseResult.succeed();
+        } catch (ExcelException e) {
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(),
+                    BizHttpStatus.IMPORT.getMsg());
+        }
+    }
+
     @ApiOperation(value = "新增", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCode")
 //    @PostMapping("/save")
     public R<JSONObject> add(@Validated @RequestBody TenantActivationCodeVo.TenantActivationCode tenantActivationCodeVo) {

+ 1 - 3
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumController.java

@@ -63,9 +63,7 @@ public class TenantAlbumController extends BaseController {
         TenantInfo tenantInfo = getTenantInfo();
         query.setTenantId(tenantInfo.getId());
         // 查询数据
-        //IPage<TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
-        //todo
-        IPage<TenantAlbum> pages = null;
+        IPage<TenantAlbumWrapper.TenantAlbumQuery> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
         // 数据类型转换
         List<TenantAlbumVo.TenantAlbum> records = JSON.parseArray(JSON.toJSONString(pages.getRecords()),
                 TenantAlbumVo.TenantAlbum.class);

+ 29 - 20
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTenantController.java

@@ -1,35 +1,18 @@
 package com.yonge.cooleshow.tenant.controller.open;
 
-import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.google.common.collect.Lists;
-import com.microsvc.toolkit.common.response.paging.PageInfo;
-import com.microsvc.toolkit.common.response.paging.QueryInfo;
-import com.yonge.cooleshow.biz.dal.entity.SysArea;
-import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
-import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantApplyRecordService;
-import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
-import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.SysAreaWrapper;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
-import com.yonge.cooleshow.tenant.io.request.SysAreaVo;
 import com.yonge.toolset.base.exception.BizException;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
 @Validated
 @RestController
 @RequestMapping("/open/tenant")
@@ -40,6 +23,12 @@ public class OpenTenantController {
     @Autowired
     private TenantApplyRecordService tenantApplyRecordService;
 
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
 
     @PostMapping("/apply")
     @ApiOperation(value = "申请")
@@ -50,4 +39,24 @@ public class OpenTenantController {
 
         return HttpResponseResult.status(true);
     }
+
+
+    @GetMapping("/bindWechat")
+    @ApiOperation(value = "绑定微信")
+    public HttpResponseResult<Boolean> bindWechat(@RequestParam("phone") String phone,
+                                                  @RequestParam("openId") String openId,
+                                                  @RequestParam("code") String code) {
+        // 校验验证码
+        boolean validCode = smsCodeService.verifyValidCode(phone, code, null);
+        if(!validCode){
+            throw new BizException("验证码错误");
+        }
+        TenantStaff tenantStaff = tenantStaffService.getByPhone(phone);
+        if (tenantStaff == null) {
+            throw new BizException("请先申请机构入驻");
+        }
+        tenantStaff.setWxOpenid(openId);
+        tenantStaffService.updateById(tenantStaff);
+        return HttpResponseResult.succeed();
+    }
 }

+ 1 - 1
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/TenantActivationCodeVo.java

@@ -26,7 +26,7 @@ public class TenantActivationCodeVo {
         @NotNull(message = "专辑购买记录的ID不能为空")
         private Long tenantAlbumPurchaseId;
 
-        @ApiModelProperty("激活码列表,批量导入时为空")
+        @ApiModelProperty("激活码列表,批量发送时为空")
         private List<String> activationCodeList = new ArrayList<>();
 
         @ApiModelProperty("学生ID列表")