puzhibing
2026-02-04 85bafa86f44fbe6646019fd8ecbab79f552ccd0a
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java
@@ -1,9 +1,50 @@
package com.xiaopeng.operation.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xiaopeng.api.model.account.SysUser;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.DateUtils;
import com.xiaopeng.common.core.utils.WebUtils;
import com.xiaopeng.common.core.web.domain.AjaxResult;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.log.annotation.Log;
import com.xiaopeng.common.log.enums.BusinessType;
import com.xiaopeng.operation.exportExcle.XpInvitationCodeExportExcel;
import com.xiaopeng.operation.exportExcle.XpWhitelistExportExcel;
import com.xiaopeng.operation.importExcel.InvitationCodeImportExcel;
import com.xiaopeng.operation.query.InvitationPageListQuery;
import com.xiaopeng.operation.query.WhitelistPageListQuery;
import com.xiaopeng.operation.service.IXpInvitationCodeService;
import com.xiaopeng.operation.service.IXpWhitelistService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>
@@ -13,8 +54,248 @@
 * @author mitao
 * @since 2026-02-03
 */
@Controller
@RequestMapping("/xp-invitation-code")
@RestController
@Api(tags = "邀请码管理")
@Slf4j
@RequestMapping("/api/v1/invitation")
public class XpInvitationCodeController {
    @Resource
    private IXpInvitationCodeService xpInvitationCodeService;
    @Resource
    private IXpWhitelistService xpWhitelistService;
    @ApiOperation(value = "邀请码管理分页列表",response = XpInvitationCode.class)
    @PostMapping("/pageList")
    public AjaxResult<PageInfo<XpInvitationCode>> pageList(@RequestBody InvitationPageListQuery query) {
        PageInfo<XpInvitationCode> pageList = xpInvitationCodeService.pageList(query);
        return AjaxResult.ok(pageList);
    }
    /**
     * 生成邀请码
     */
    @PutMapping("/add")
    @ResponseBody
    @ApiOperation(value = "生成邀请码")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "手机号 多个逗号隔开", name = "phones", dataType = "String", required = true)
    })
    @Transactional
    public AjaxResult add(@RequestParam("phones") String phones){
        Map<String, Long> codeMap = xpInvitationCodeService.list().stream()
                .collect(Collectors.toMap(XpInvitationCode::getInvitationCode, XpInvitationCode::getId));
        if (StringUtils.hasLength(phones)){
            List<XpInvitationCode> addInvitationCodeList = new ArrayList<>();
            List<XpWhitelist> addWhitelistList = new ArrayList<>();
            for (String phone : Arrays.asList(phones.split(","))) {
                XpInvitationCode xpInvitationCode = new XpInvitationCode();
                // 生成随机六位数邀请码包含数字和大写字母
                String code = generateInviteCode();
                // 若生成出已存在的邀请码 重新生成
                Long l = codeMap.get(code);
                while (l!=null){
                    code = generateInviteCode();
                    l = codeMap.get(code);
                }
                xpInvitationCode.setInvitationCode(code);
                xpInvitationCode.setBindAccount(phone);
                xpInvitationCode.setBindTime(LocalDateTime.now());
                xpInvitationCode.setStatus(2);
                addInvitationCodeList.add(xpInvitationCode);
                XpWhitelist xpWhitelist = new XpWhitelist();
                xpWhitelist.setAccount(phone);
                xpWhitelist.setStatus(true);
                xpWhitelist.setIsPriorityDispatch(false);
                xpWhitelist.setWhitelistSource(2);
                addWhitelistList.add(xpWhitelist);
            }
            xpInvitationCodeService.saveBatch(addInvitationCodeList);
            xpWhitelistService.saveBatch(addWhitelistList);
            return AjaxResult.success();
        }else {
            return AjaxResult.error("请输入邀请手机号");
        }
    }
    /**
     * 解绑
     */
    @PutMapping("/unbind")
    @ResponseBody
    @ApiOperation(value = "解绑")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "id", name = "id", dataType = "Long", required = true)
    })
    public AjaxResult unbind(@RequestParam("id") Long id){
        UpdateWrapper<XpInvitationCode> xpInvitationCodeUpdateWrapper = new UpdateWrapper<>();
        xpInvitationCodeUpdateWrapper.eq("id",id);
        xpInvitationCodeUpdateWrapper.set("status",3);
        xpInvitationCodeUpdateWrapper.set("bind_account", null);
        xpInvitationCodeService.update(xpInvitationCodeUpdateWrapper);
        return AjaxResult.success();
    }
    @ApiOperation(value = "点位导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<InvitationCodeImportExcel> invitationCodeImportExcels = new ArrayList<>();
        InvitationCodeImportExcel invitationCodeImportExcel = new InvitationCodeImportExcel();
        invitationCodeImportExcels.add(invitationCodeImportExcel);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), InvitationCodeImportExcel.class, invitationCodeImportExcels);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("邀请码导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("邀请码导入模板下载失败!");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Log(title = "邀请码导入", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "邀请码导入")
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/importExcel")
    public AjaxResult<String> importExcel(@RequestPart("file") MultipartFile file) {
        ImportParams params = new ImportParams();
//        params.setTitleRows(1); // 标题行数
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
//        List<CustomerImportFailedData> failedData = new ArrayList<>();
        List<InvitationCodeImportExcel> invitationCodeImportExcels;
        try {
            inputStream = file.getInputStream();
            invitationCodeImportExcels = ExcelImportUtil.importExcel(inputStream,
                    InvitationCodeImportExcel.class, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("邀请码导入失败:{}", e.getMessage());
            throw new ServiceException("邀请码导入失败!");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new ServiceException(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(invitationCodeImportExcels)) {
            throw new ServiceException("邀请码数据为空!");
        }
        // 校验邀请码是否有重复的
        long count = invitationCodeImportExcels.stream().map(InvitationCodeImportExcel::getInvitationCode)
                .distinct().count();
        if (count!=invitationCodeImportExcels.size()){
            return AjaxResult.error("邀请码存在重复!");
        }
        Map<String, Long> codeMap = xpInvitationCodeService.list().stream()
                .collect(Collectors.toMap(XpInvitationCode::getInvitationCode, XpInvitationCode::getId));
        JSONObject result = new JSONObject();
        List<XpInvitationCode> addList = new ArrayList<>();
        List<XpWhitelist> addWhitelistList = new ArrayList<>();
        for (InvitationCodeImportExcel locationExcel : invitationCodeImportExcels) {
            Long id = codeMap.get(locationExcel.getInvitationCode());
            if (id!=null){
                result.append("邀请码:[", locationExcel.getInvitationCode()+"]已存在");
            }
            locationExcel.setBindTime(locationExcel.getBindTime());
            XpInvitationCode xpInvitationCode = new XpInvitationCode();
            xpInvitationCode.setInvitationCode(locationExcel.getInvitationCode());
            xpInvitationCode.setBindAccount(locationExcel.getBindAccount());
            if (StringUtils.hasLength(locationExcel.getBindTime())){
                String replace = locationExcel.getBindTime().replace(".", "-");
                String res = replace.replace("/", "-");
                locationExcel.setBindTime(res);
            }
            xpInvitationCode.setBindTime(DateUtils.stringToLocalDateTime(locationExcel.getBindTime()));
            if (StringUtils.hasLength(locationExcel.getBindAccount())){
                xpInvitationCode.setStatus(2);
            }else{
                xpInvitationCode.setStatus(1);
            }
            XpWhitelist xpWhitelist = new XpWhitelist();
            xpWhitelist.setAccount(locationExcel.getBindAccount());
            xpWhitelist.setStatus(true);
            xpWhitelist.setIsPriorityDispatch(false);
            xpWhitelist.setWhitelistSource(2);
            addWhitelistList.add(xpWhitelist);
            addList.add(xpInvitationCode);
        }
        if(!result.isEmpty()){
            return AjaxResult.success(result.toString());
        }
        xpInvitationCodeService.saveBatch(addList);
        xpWhitelistService.saveBatch(addWhitelistList);
        return AjaxResult.success();
    }
    @ApiOperation(value = "邀请码导出")
    @PostMapping(value = "/exportExcel")
    public void exportExcel(@RequestBody InvitationPageListQuery query) {
        List<XpInvitationCode> list = xpInvitationCodeService.exportList(query);
        List<XpInvitationCodeExportExcel> xpWhitelistExportExcels = new ArrayList<>();
        for (XpInvitationCode xpInvitationCode : list) {
            XpInvitationCodeExportExcel xpWhitelistExportExcel = new XpInvitationCodeExportExcel();
            xpWhitelistExportExcel.setId(xpInvitationCode.getId());
            xpWhitelistExportExcel.setBind_account(xpInvitationCode.getBindAccount());
            xpWhitelistExportExcel.setInvitationCode(xpInvitationCode.getInvitationCode());
            LocalDateTime createTime = xpInvitationCode.getCreateTime();
            LocalDateTime bindTime = xpInvitationCode.getBindTime();
            // 将LocalDateTime转化为yyyy-MM-dd HH:mm:ss格式字符串
            xpWhitelistExportExcel.setCreateTime(createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            xpWhitelistExportExcel.setBindTime(bindTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            xpWhitelistExportExcels.add(xpWhitelistExportExcel);
        }
        //1.获取excel模板
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpInvitationCodeExportExcel.class, xpWhitelistExportExcels);
        HttpServletResponse response = WebUtils.response();
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("邀请码列表.xls", "utf-8");
            response.setHeader("Content-dispodition", "attachment;filename=" + fileName);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 批量删除
     */
    @PutMapping("/deleteByIds")
    @ResponseBody
    @ApiOperation(value = "批量删除")
    public AjaxResult deleteByIds(List<Long> ids){
        xpInvitationCodeService.removeBatchByIds(ids);
        return AjaxResult.success();
    }
    private static final String CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final int CODE_LENGTH = 6;
    private static final Random RANDOM = new Random();
    public static String generateInviteCode() {
        StringBuilder code = new StringBuilder(CODE_LENGTH);
        for (int i = 0; i < CODE_LENGTH; i++) {
            int index = RANDOM.nextInt(CHARACTERS.length());
            code.append(CHARACTERS.charAt(index));
        }
        return code.toString();
    }
}